(T-SQL) Join two columns to one common column - sql

I have this problem:
TABLE1:
| ID | DESCRIPTION |
| 10 | Apple |
| 20 | Banana |
| 33 | Pineapple |
| 47 | Orange |
TABLE2:
| ID | FRUIT1 | FRUIT2 |
| 1 | 10 | 47 |
| 2 | 47 | 10 |
| 3 | 33 | 20 |
| 4 | 20 | 33 |
If I select all data in TABLE2, I want in output the name of the fruits (TABLE1.DESCRIPTION) for TABLE2.FRUIT1 and TABLE2.FRUIT2 and not the ID.
How can I do it?

Join table2 twice with different alias name
select t2.id, f1.description, f2.description
from table2 t2
left join table1 f1 on f1.id = t2.fruit1
left join table1 f2 on f2.id = t2.fruit2

You can join back to Table1 twice; you just need to give different table aliases:
SELECT ID, T1a.Description [Fruit1], T1b.Description [Fruit2]
FROM Table2 T2
INNER JOIN Table1 T1a
ON T2.Fruit1 = T1a.ID
INNER JOIN Table1 T1b
ON T2.Fruit1 = T1b.ID

Use a union to combine the columns together like this:
Select t1.Description
from Table2 t2
INNER JOIN Table1 t1 on t1.ID = t2.Fruit1
UNION
Select t1.Description
from Table2 t2
INNER JOIN Table1 t1 on t1.ID = t2.Fruit2

Related

Joining Two Tables, Same ID - Return both IDs even if Null

I have two tables
+-----+----------+
| SKU | Quantity |
+-----+----------+
| ABC | 30 |
| DEF | 40 |
+-----+----------+
+-----+----------+
| SKU | OnOrder |
+-----+----------+
| ABC | 90 |
| XYZ | 80 |
+-----+----------+
I want to join both tables on SKU when there is a match, but also return SKU from both tables when there isn't a match. So the results would be:
+-----+---------+---------+
| SKU | OnOrder | OnOrder |
+-----+---------+---------+
| ABC | 90 | 30 |
| DEF | 40 | |
| XYZ | | 80 |
+-----+---------+---------+
I'm thinking this would be accomplished by using a left join and a right join and by doing a union but I can't seem to get the code right.
Your help is much appreciated!
You can use a full join:
select coalesce(t1.sku, t2.sku), t1.quantity, t2.onorder
from table1 t1 full join
table2 t2
on t1.sku = t2.sku;
If your database doesn't support full join, the best workaround is probably:
select t1.sku, t1.quantity, t2.onorder
from table1 t1 left join
table2 t2
on t1.sku = t2.sku
union all
select t2.sku, null, t2.onorder
from table2
where not exists (select 1 from table1 t1 where t1.sku = t2.sku);
You can first select all the SKU values and then join that to both tables:
with skus(sku) as (
select sku from table1
union
select sku from table2
)
select a.sku, b.quantity, c.onorder
from skus a
left join table1 b on a.sku = b.sku
left join table2 c on a.sku = c.sku;

trouble with postgresql subquery

Here are my tables:
table1:
ID | data1 | data2
1 | xxx | xxx
2 | xxx | xxx
table2:
ID | table1_id
20 | 1
21 | 1
25 | 2
26 | 2
table3:
ID | table2_id
30 | 20
31 | 21
32 | 25
33 | 26 <--
I have marked the relevant row by an arrow (table3: ID=33 | table2_id=26)
Now, I want the matching ID with data 1 and data 2 from table 1. In this case: 2
I tried something ...
SELECT t1."ID"
FROM table AS t1
INNER JOIN table2 AS tb2
ON t1."ID" = t2."ID"
INNER JOIN table3 AS t3
ON t2."ID" = 26
... but it returns nothing. Have anybody a working subquery for me :)
you join on the wrong fields
SELECT t1."ID"
FROM table AS t1
INNER JOIN table2 AS t2
ON t1."ID" = t2.table1_id
INNER JOIN table3 AS t3
ON t2."ID" = t3.table2_id
WHERE t3."ID" = 33

Join three tables with counts

I have these three tables (Soknad, Prognose and Did) in the SQL Server database:
Table Soknad has columns: S_ID (key), S_REFNR
Table Prognose has columns: P_ID (key), P_S_ID
Table Did has columns: D_ID (key), D_S_ID, Did_Something
Prognose.P_S_ID is foreign key to Soknad.S_ID.
Did.D_S_ID is foreign key to Soknad.S_ID.
The tables are like this:
SOKNAD
S_ID | S_REFNR |
1 | abc |
2 | cbc |
3 | sdf |
PROGNOSE
P_ID | P_S_ID |
10 | 1 |
11 | 2 |
DID
D_ID | D_S_ID | D_Did_Something |
100 | 1 | 1 |
101 | 1 | 1 |
102 | 1 | 0 |
103 | 2 | 1 |
104 | 2 | 1 |
I want to join these tables (like a view or select statement). From the Did table a count of column Did_Something should be returned, as well as a count of the same column where the value is 1 (one).
The result should be:
S_ID | S_REFNR | P_ID | Count_D_Did_Something | Count_D_Did_Something_Is_One |
1 | abc | 10 | 3 | 2 |
2 | cbc | 11 | 2 | 2 |
3 | sdf | | | |
Any help would be appreciated!
I believe what you want to do is join two tables and put the counts where the rows match the left table in separate columns for each table.
This would accomplish that.
select t1.id, count(t2.id) t2_count , count(t3.id) t3_count
from table1 as t1
left outer join table2 as t2 on t2.table1_id = t1.id
left outer join table3 as t3 on t3.table1_id = t1.id
group by t1.id;
To accomplish the counts you want based on criteria from one of the outer joined tables, you can do that this way, using a derived table...
select t1.id, count(t2.id) t2_count, count(tt2.mCount) Did_SomethingCount, count(t3.id) t3_count
from table1 as t1
left outer join table2 as t2 on t2.table1_id = t1.id
left outer join (select count(*), table1_id mCount from table2 where Did_Something = 1 group by table1_id) as tt2 on tt2.table1_id = t1.id
left outer join table3 as t3 on t3.table1_id = t1.id
group by t1.id;
Here you go:
select s.s_id,
p.p_id,
count(d.Did_Something) as Count_D_Did_Something, -- nulls won't be counted
sum(CASE WHEN d.Did_Something = 1 THEN 1 ELSE 0 END) as Count_D_Did_Something_is_one
from Soknad as s
left join Prognose as p on p.P_S_ID = s.s_id
left join Did as d on d.D_S_ID = s.s_id
This should be simply give the results you need. Note, I simply summed up when you want count to be for values having one,
SELECT S.S_ID, S.REFNR, P.P_ID, COUNT(D.D_DID_SOMETHING) AS COUNT_D_DID_SOMETHING,
SUM(D_DID_SOMETHING) AS COUNT_D_DID_SOMETHING_IS_ONE
FROM SOKNAD AS S
INNER JOIN PROGNOSE AS P
ON P.P_S_ID = S.S_ID
INNER JOIN DID AS D
ON D.D_S_ID = S.S_ID
GROUP BY S.S_ID, S.REFNR, P.P_ID

Select datas from multiple tables using one common table in sql server 2005

I have many tables and one common table that have ids of all these tables
for eg:
Table1
| ID | VALUE | DATE |
---------------------------
| 1 | 200 | 25/04/2013 |
| 2 | 250 | 26/05/2013 |
Table2
| ID | VALUE | DATE |
---------------------------
| 1 | 300 | 25/05/2013 |
| 2 | 100 | 12/02/2013 |
Table3
| ID | VALUE | DATE |
---------------------------
| 1 | 500 | 5/04/2013 |
| 2 | 100 | 1/01/2013 |
and one common table
| ID | TABLE | TABLEID |
-------------------------
| 1 | table1 | 1 |
| 2 | table3 | 1 |
| 3 | table2 | 1 |
| 4 | table1 | 2 |
| 5 | table2 | 2 |
| 6 | table3 | 2 |
and using this common table i need to select all datas in above 3 tables
eg:
output
id table tableid value date
1 table1 1 200 25/04/2013
2 table3 1 500 5/04/2013
3 table2 1 300 25/05/2013
4 table1 2 250 26/05/2013
5 table2 2 100 12/02/2013
6 table3 2 100 1/01/2013
If you don't want to use UNION ALL you can use COALESCE for the same using LEFT JOIN like this:
SELECT c.*
, COALESCE(t1.Value, t2.Value,t3.Value) AS Value
, COALESCE(t1.Date, t2.Date,t3.Date) AS Date
FROM Common c
LEFT JOIN Table1 t1 ON c.tableid = t1.[id]
AND [Table] = 'table1'
LEFT JOIN Table2 t2 ON c.tableid = t2.[id]
AND [Table] = 'table2'
LEFT JOIN Table2 t3 ON c.tableid = t3.[id]
AND [Table] = 'table3'
ORDER BY ID;
See this SQLFiddle
By this way you can reduce your task to join all records using UNION ALL. But for the given data structure you have to join all tables anyhow.
You need to join all tables with common table separately then join them using UNION ALL:
SELECT *
FROM Common c
JOIN Table1 t1 ON c.tableid = t1.[id]
AND [Table] = 'table1'
UNION ALL
SELECT *
FROM Common c
JOIN Table2 t2 ON c.tableid = t2.[id]
AND [Table] = 'table2'
UNION ALL
SELECT *
FROM Common c
JOIN Table3 t3 ON c.tableid = t3.[id]
AND [Table] = 'table3';
See this SQLFiddle
You can UNION ALL the tables adding flag column in the process and then JOIN the result with common table.
WITH CTE_Tables AS
(
SELECT 'Table1' AS Tab, * FROM Table1
UNION ALL
SELECT 'Table2' AS Tab, * FROM Table2
UNION ALL
SELECT 'Table3' AS Tab, * FROM Table3
)
SELECT *
FROM CommonTable c1
LEFT JOIN CTE_Tables cte ON cte.ID = c1.TableID AND cte.Tab = c1.[Table]
SQLFiddle DEMO

MySQL get data from another table with duplicate ID/data

How to query data from table_1 which ID is not available on table_2 that has duplicate ID's. See example below.
I want to get ID 5 and 6 of Table 1 from Table 2
Table 1
-------------
| ID | Name |
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
| 5 | e |
| 6 | f |
-------------
Table 2
-------------
Table 1 ID |
| 1 |
| 1 |
| 2 |
| 2 |
| 2 |
| 3 |
| 4 |
-------------
Thanks!
Minus query would be very helpful, see this link: minus query replacement
for your data this would look like this:
SELECT table_1.id FROM table_1 LEFT JOIN table_2 ON table_2.id = table_1.id WHERE table_2.id IS NULL
Use:
SELECT t.id
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.id = t1.id
WHERE t2.id IS NULL
Using NOT EXISTS:
SELECT t.id
FROM TABLE_1 t1
WHERE NOT EXISTS(SELECT NULL
FROM TABLE_2 t2
WHERE t2.id = t1.id)
Using NOT IN:
SELECT t.id
FROM TABLE_1 t1
WHERE t1.id NOT IN (SELECT t2.id
FROM TABLE_2 t2)
Because there shouldn't be NULL values in table2's id column, the LEFT JOIN/IS NULL is the fastest means: http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/
If I am understanding you correctly you want to do an outer join. In this case it would be:
SELECT * FROM
table_1 LEFT JOIN ON table_2
ON table_1.id = table_2.id
WHERE table_2.id is NULL
This one does what you want:
Select t1.id
From table1 t1
Left Join table2 t2
On t2.id = t1.id
Where t2.id Is Null
Result:
id
--
5
6