play_by_play table I want to connect to multiple other tables so I can see the text instead of id. play_by_play table has three different columns that use team_id from another table.
When I run this query I get no results. No error, just no results. I get a few results when removing AND play_by_play.player3_team_id = team.team_id so I'm sure there's a correct way.
SELECT
play_by_play.id,
play_by_play.game_id,
play_by_play.event_msg_action_type
FROM play_by_play
INNER JOIN event_message_type
ON play_by_play.event_msg_type_id = event_message_type.id
INNER JOIN game
ON game.game_id = play_by_play.game_id
INNER JOIN team
ON play_by_play.player1_team_id = team.team_id
AND play_by_play.player2_team_id = team.team_id
AND play_by_play.player3_team_id = team.team_id
LIMIT 500
Any resources to understand SQL syntax is appreciated. How to put these pieces in the correct order?
You should use table team three times
...
INNER JOIN team team1
ON play_by_play.player1_team_id = team1.team_id
INNER JOIN team team2
ON play_by_play.player2_team_id = team2.team_id
INNER JOIN team team3
AND play_by_play.player3_team_id = team3.team_id
...
I'm writing a query in SQLite, for Android, with a schema like this (extremely simplified here, just the fields I need)
GROUP
group_id primary_key,
parent_group_id nullable
PERSON
person_id primary_key,
parent_group
I need to count the number of persons in a group and in its descendant groups, given the group_id of the group I want to count for. I think I need a CTE query and I've been reading all morning about them, but I'm not grasping how they work.
You're on the right track with needing a CTE. Something like:
WITH tree AS
(SELECT g.group_id AS root,
g.group_id AS parent,
p.person_id AS person
FROM "group" AS g
LEFT JOIN person AS p ON g.group_id = p.parent_group
WHERE g.group_id = #desired_group
UNION ALL
SELECT t.root, g.group_id, p.person_id
FROM tree AS t
JOIN "group" AS g ON t.parent = g.parent_group_id
LEFT JOIN person AS p on g.group_id = p.parent_group)
SELECT count(DISTINCT person)
FROM tree;
Start by selecting the desired group and its members, and then recursively select all members of groups with the given parent group. Finally, count all the unique users that were found.
db<>fiddle example.
I powered through all the articles I could find and via a lot of trials and errors, I got here (please note that in my real database person is model):
WITH RECURSIVE is_in_group(group_id, group_name, parent_group_id) AS(
SELECT gr.group_id, gr.group_name, gr.parent_group_id FROM _group as gr WHERE gr.group_id = :groupId
UNION ALL
SELECT g.group_id, g.group_name, g.parent_group_id FROM _group as g
JOIN is_in_group as c ON g.parent_group_id = c.group_id
)
SELECT q.group_id, q.group_name, count(m.model_id) as model_count FROM is_in_group as q
LEFT JOIN _model m ON m.parent_group_id = group_id
GROUP BY q.group_id
This will give me a list of groups (including the root one), with a group_id, group_name and a model_count of models in each group. With this I can simply sum to get the total or look at the row with the searched group_id to know how many models are just in this group.
I have two tables. Config and Data. Config table has info to define what I call "Predefined Points". The columns are configId, machineId, iotype, ioid, subfield and predeftype. I have a second table that contains all the data for all the items in the config table linked by configId. Data table contains configId, timestamp, value.
I am trying to return each row from the config table with 2 new columns in the result which would be min timestamp of this particular predefined point and max timestamp of this particular predefined point.
Pseudocode would be
select a.*, min(b.timestamp), max(b.timestamp) from TrendConfig a join TrendData b on a.configId = b.configId where configId = (select configId from TrendConfig)
Where the subquery would return multiple values.
Any idea how to formulate this?
Try an inner join:
select a.*, b.min(timestamp), b.max(timestamp)
from config a
inner join data b
on a.configId = b.configID
I was able to find an answer using: Why can't you mix Aggregate values and Non-Aggregate values in a single SELECT?
The solution was indeed GROUP BY as CL mentioned above.
select a.*, min(b.timestamp), max(b.timestamp) from TrendConfig a join TrendData b on a.configId = b.configId group by a.configId
SQLServer2008R2 and ASP.NET(VB) - VS2012
I am tring to use many-to-many relationship. I have a table to enter users, another one for the incidents and created a join table with the primary key from both the tables. I am trying to display top 20 incidents from the incident table and get the patron id from join table and then get the name of the patron from patron table. For an incident with two patrons, it creates two rows. I tried to use GROUP by but the query did not like it. Is there a way that I can display only one incident id with both patron names listed?
SELECT TOP (20)
tblIncident.Inci_ID
,tblIncident.Library
,tblIncident.Inci_date
,tblIncident.Inci_time
,tblIncident.Created_By
,tblJoin.PatronID AS Patron_ID
,tblPatron.FName + ' ' + tblPatron.LName AS FullName
FROM tblIncident
INNER JOIN tblJoin ON tblIncident.Inci_ID = tblJoin.InciID
INNER JOIN tblPatron ON tblJoin.PatronID = tblPatron.PatronID
WHERE tblIncident.Active = 'True'
ORDER BY tblIncident.Inci_date DESC
I am trying to update Table B of a database looking like this:
Table A:
id, amount, date, b_id
1,200,6/31/2012,1
2,300,6/31/2012,1
3,400,6/29/2012,2
4,200,6/31/2012,1
5,200,6/31/2012,2
6,200,6/31/2012,1
7,200,6/31/2012,2
8,200,6/31/2012,2
Table B:
id, b_amount, b_date
1,0,0
2,0,0
3,0,0
Now with this query I get all the data I need in one select:
SELECT A.*,B.* FROM A LEFT JOIN B ON B.id=A.b_id WHERE A.b_id>0 GROUP BY B.id
id, amount, date, b_id, id, b_amount, b_date
1,200,6/31/2012,1,1,0,0
3,400,6/29/2012,1,1,0,0
Now, I just want to copy the selected column amount to b_amount and date to b_date
b_amount=amount, b_date=date
resulting in
id, amount, date, b_id, id, b_amount, b_date
1,200,6/31/2012,1,1,200,6/31/2012
3,400,6/29/2012,1,1,400,6/29/2012
I've tried COALESCE() without success.
Does someone experienced have a solution for this?
Solution:
Thanks to the answers below, I managed to come up with this. It is probably not the most efficient way but it is fine for a one time only update. This will insert for you the first corresponding entry of each group.
REPLACE INTO A SELECT id, amount, date FROM
(SELECT A.id, A.amount, B.id as Bid FROM A INNER JOIN B ON (B.id=A.B_id)
ORDER BY A.id DESC)
GROUP BY Bid;
So what you are looking for seems to be a JOIN inside of an UPDATE query. In mySQL you would use
UPDATE B INNER JOIN A ON B.id=A.b_id SET B.amount=A.amount, B.date=A.date;
but this is not supported by sqlite as this probably related question points out. However, there is a workaround using REPLACE:
REPLACE INTO B
SELECT B.id, A.amount, A.date FROM A
LEFT JOIN B ON B.id=A.b_id
WHERE A.b_id>0 GROUP BY B.id;
The query will simply fill in the values of table B for all columns which should keep their state and fill in the values of table A for the copied values. Make sure the order of the columns in the SELECT statement meet your column order of table B and all columns are mentioned or you will loose these field's data. This is probably dangerous for future changes on table B. So keep in mind to change the column order/presence of this query when changing table B.
Something a bit off topic, because you did not ask for that: A.b_id is obviously a foreign key to B.id. It seems you are using the value 0 for the foreign key to express that there is no corresponding entry in B. (Inferred from your SELECT with WHERE A.b_id>0.) You should consider using the null value for that. When you are using INNER JOIN then instead of LEFT JOIN you can drop the WHERE clause entirely. The DBS will then sort out all unsatisfied relations.
WARNING Some RDBMS will return 2 rows as you show above. Others will return the Cartesian product of the rows i.e. A rows times B rows.
One tricky method is to generate SQL that is then executed
SELECT "update B set b.b_amount = ", a.amount, ", b.b_date = ", a.date,
" where b.id = ", a.b_id
FROM A LEFT JOIN B ON B.id=A.b_id WHERE A.b_id>0 GROUP BY B.id
Now add the batch terminator and execute this SQL. The query result should look like this
update B set b.b_amount = 200, b.b_date = 6/31/2012 where b.id = 1
update B set b.b_amount = 400, b.b_date = 6/29/2012 where b.id = 3
NOTE: Some RDBMS will handle dates differently. Some require quotes.