Multi-Table Selecting with Count of Foreign Key Referred Rows - sql

I've tables related with foreign keys and i try to prepare a view to compose them via inner joins on SQL Server. I don't know if using inner join's is the way, but I can't get what I want anyway.
Tables are like below (I have more than 2 tables):
Table1:
| ID | Bla Bla... |
Table2:
| ID | Table1ID | Bla Bla... |
The query I tried is like this:
Select
Table1.ID, COUNT(Table2.ID) as FooCount
From
Table1
Inner Join
Table2 on Table2.Table1ID = Table1.ID
The result I want to see should be this:
| ID | FooCount |
-----------------------
| 1 | 45 |
| 2 | 75 |
| 3 | 98 |
| 4 | 100 |
| 5 | 11 |
| 6 | 37 |
How can I do this?

You don't even need a join to do this:
SELECT Table1Id AS ID, COUNT(*) as FooCount FROM Table2 GROUP BY Table1Id

Related

Select two tables side by side

I have two tables filled with two files of which table1 always has one row more than the second.
I want to merge the two tables into one. When I use a right join e.g.
select *
from table2
right join table1 on table1.id = table2.id and table1.eq_nb = table2.eq_nb
I will have the 4 combinations for eq_nb = 25 because it is repeated two times.
But I rather want to stick the columns side by side
To know, I don't have conditions on arrival and depart time of each eq_nb (I can't add something like datediff(second,table1.arrival_time,table2.depart_time) < X )
table1:
id | eq_nb | arival_time
-------------------------------------
1 | 25 | 05:30:15.231
-------------------------------------
2 | 50 | 06:30:15.231
-------------------------------------
3 | 7 | 07:30:15.231
-------------------------------------
1 | 25 | 08:30:15.231
-------------------------------------
5 | 27 | 09:30:15.231
-------------------------------------
table2:
id | eq_nb | depart_time
----------------------------------
1 | 25 | 05:31:15.231
----------------------------------
2 | 50 | 06:31:15.231
----------------------------------
3 | 7 | 07:31:15.231
----------------------------------
1 | 25 | 08:31:15.231
----------------------------------
desired result:
id | eq_nb | arrival_time | depart_time
-------------------------------------------------------
1 | 25 | 05:30:15.231 | 05:31:15.231
-------------------------------------------------------
2 | 50 | 06:30:15.231 | 06:31:15.231
-------------------------------------------------------
3 | 7 | 07:30:15.231 | 07:31:15.231
-------------------------------------------------------
1 | 25 | 08:30:15.231 | 08:31:15.231
--------------------------------------------------------
5 | 27 | 09:30:15.231 | NULL
--------------------------------------------------------
left join should do what you want:
select *
from table1 t1 left join
table2 t2
on t1.id = t2.id and t1.eq_nb = t2.eq_nb;
Given your data, the ids are unique, so there should be no duplication. Note: This is equivalent to your first query; left join is typically easier to follow because all the rows in the first table are in the result set.
Here is a db<>fiddle, illustrating that it works.

SQL query join- unrelated tables

Can someone help me to join the two tables without any primary or secondary keys. Sample table is
TABLE 1
| ID | NAME |
| 1 | x |
| 2 | Y |
| 3 | z |
TABLE 2
| Num | NAME | DATE |
| 52 | X | 12-aug-17 |
| 53 | X | 11-apr-17 |
| 62 | X | 10-aug-11 |
| 12 | y | 2-jan-16 |
| 23 | Y | 3-apr-18 |
I want retrieve data from X
select *
from table2
where name = 'x';
| Num | NAME | DATE |
| 52 | X | 12-aug-17 |
| 53 | X | 11-apr-17 |
| 62 | X | 10-aug-11 |
Now I will get three data from table2. I'm little stuck after this step. I want to get top of data the from table 2 and combine with table one.
I want final output should be
| ID | NAME | Num | DATE |
| 1 | x | 52 | 12-aug-17 |
Can someone suggest me how can I join this table? Its easy to join when we have any primary key but here not the case
Thanks
You can use this:
SELECT TOP(1) table1.ID, table2.Num, table2.Name, table2.DATE
FROM table2 INNER JOIN table1 ON table1.NAME = table2.NAME
WHERE table2.NAME = 'x'
ORDER BY table2.DATE ASC
OR
SELECT table1.ID, table2.Num, table2.Name, table2.DATE
FROM table1 INNER JOIN
(SELECT TOP(1) * FROM table2 WHERE NAME = 'x' ORDER BY DATE ASC) table2
ON table1.NAME = table2.NAME
You need to get the maximum DATE using a subquery, as in:
select t1.id, t2.*
from table1 t1
join table2 t2 on t2.name = t1.name
where t2.date = (
select max(date) from table2 where name = 'x'
);

looking for a function

I am new to SQL and I am trying to create a query that will give me the same result as LEFT OUTER JOIN but between two data bases. For example, in DB1 there are 100 records with the value X in specific column and in DB2 there 80 records. I want a query that will give the 20 missing records.
Thanks.
If you mean "between two tables":
select Table1.*
from Table1
left join Table2
on Table1.id = Table2.id
where Table2.id is null
This gives everything in Table2 that does not match
For more visual info on joins, go here
For basic info on SQL, try here
DB1 (table_users)
+----+-----------+--------------+
| id | username | lastname |
+----+-----------+--------------+
| 1 | xxxxxx | mmmmmmm |
+----+-----------+--------------+
| 2 | bbbbbb | wwwwwww |
+----+-----------+--------------+
DB2 (table_users)
+----+-----------+--------------+
| id | username | lastname |
+----+-----------+--------------+
| 1 | xxxxxx | mmmmmmm |
+----+-----------+--------------+
| 2 | bbbbbb | wwwwwwww |
+----+-----------+--------------+
| 3 | ccccc | ppppppppppp |
+----+-----------+--------------+
SELECT *
FROM DB2.table_users
WHERE phone_number NOT IN (SELECT * FROM DB2.table_users);
I think it servers the same purpose, except that your dealing with tables from different databases.

GROUP BY in Django ORM with aggregation

I need to implement such query:
Table1
|Id | Name |
| 1 | Peter |
| 2 | Andrew |
Table2
| Score | Table1Id |
| 10 | 1 |
| 20 | 1 |
| 100 | 1 |
| 0 | 2 |
| 30 | 2 |
I need select for all names {name, min_score, max_score}
{Peter, 10, 100}
{Andrew, 0, 30}
Something like:
SELECT DISTINCT MIN(score), MAX(score) Table1.name FROM Table1, Table2 WHERE Table1.Id = Table2.Table1Id GROUP BY Table1.Name
In ORM it something like:
Table2.objects.all().annotate(min_score=Min('score'), max_score=Max('score')).values('Table1.Name!!!!', 'min_score', 'max_score')
try this:
Table2.objects.values('table1__name').annotate(min_score=Min('score'), max_score=Max('score'))
the annotated fields will be added to the result, they don't need to go in values(...), but whatever you put in values(...) will be used as the GROUP BY field(s)

Can I combine values from multiple rows in another table into multiple columns of one row using SQL?

I have two tables:
T1:
| M_ID | P_ID1 | P_ID2 | rest of T1 columns |
| 0 | 0 | 1 | ... |
| 1 | 2 | 3 | ... |
T2:
| P_ID | Type | A | B |
| 0 | 1 | a | e |
| 1 | 2 | b | f |
| 2 | 1 | c | g |
| 3 | 2 | d | h |
Now, I want to have a query that selects this:
| M_ID | P_1a | P_1b | P_2a | P_2b | rest of T1 columns |
| 0 | a | e | b | f | ... |
| 1 | c | g | c | h | ... |
So, in words: I want to select all columns from T1, but I want to replace P_ID1 with the columns from T2, where the P_ID is equal to P_ID1, and the type is 1, and basically the same for P_ID2.
I can obviously get the information I need with multiple queries, but I was wondering if there is a way that I can do this with one query. Any ideas?
I'm currently using SQL Server 2008r2, but I'd also be interested in solutions for other database software.
Thanks for the help!
Sure, you just need to use a join:
select T1.M_ID, t2_1.A as P_1a, t2_1.B as P_1b, t2_2.A as P_2a, t2_2.B as P_2b, ...
from T1, T2 t2_1, T2 t2_2
where T1.P_ID1 = t2_1.P_ID and T1.P_ID2 = t2_2.P_ID
basically we are joining T1 onto T2 twice, once for the P_1 values and a second time for the P_2 values. You need to alias T2 when you join it twice to distinguish between the two (that's what the t2_1 and t2_2 are - a means of distinguishing between the two instances of the joined T2).
This is the same as #John Pickup's solution only using modern join syntax:
select T1.M_ID, t2_1.A as P_1a, t2_1.B as P_1b, t2_2.A as P_2a, t2_2.B as P_2b, ...
from T1
join T2 t2_1 on T1.P_ID1 = t2_1.P_ID
join T2 t2_2 on T1.P_ID2 = t2_2.P_ID
I only post a seperate answer, as there is no code formatting in comments as you get told here