SQL three tables using only JOIN - sql

I have three tables: T1 has id's from T2 (client) and T3 (supplier), it also acts a black list: T1's rows with client's and supplier's id.
I want to get the supplier's id the client can buy from.
.
currently T1 has three rows:
T1_id | T2_id | T3_id
1 1 3
2 1 4
3 2 3
I tried:
select T3.id
from T1
left join T2 on T2.id = T1.T2_id
right join T3 on T3.id != T1.T3_id
where T2.id = 1
the output is:
1
2
3
1
2
4
It should be only 1 and 2. What am I missing? It works fine with T2.id = 2.

You can also do this like that
select T3.id from T1, T2, T3
where
T1.T2_id = T2.id and
T3.id <> T1.T3_id and
T2.id = 1
I hope this helps

So you have
List of clients
List of suppliers
A map between clients and suppliers.
This should be your table layout.
clients
---------
client_id [PK]
client_label
suppliers
---------
supplier_id [PK]
supplier_label
client_suppliers
----------------
client_supplier_id [PK]
client_id
supplier_id
Then you just select which suppliers are mapped to a particular client.
SELECT
supplier_id
, supplier_label
FROM
suppliers T1
INNER JOIN
client_suppliers T2 ON T2.supplier_id = T1.supplier_id
WHERE
T2.client_id = 1

Related

Join two tables with switch case in order to avoid one to many join

I have two tables, t1 and t2.
Table t1:
Name address id
---- ------- --
rob 32 cgr 12
mary 31 lmo 42
tom axel St 2
Table t2:
ID Flag expense
-- ---- --------
12 Shop 1200
12 Educ 14000
42 educ 4000
Now I will have to create a table which will have attributes from t1 plus two more attributes that is expense in shop and expense in educ
Table t3
Name address id Shop_ex Educ_ex
---- ------- -- ------- -------
rob 32 cgr 12 1200 14000
mary 31 lmo 42 NULL 4000
tom axel st 2 NULL NULL
How to accomplish this?
I tried doing a left join t2 with switch case but it gives me multiple record as the join is becoming one to many.
select
t1.name, t1.address, t1.id,
case
when t2.flag = "shop" then t2.expense
else null
end as shop_ex
case
when t2.flag = "educ" then t2.expense
else null
end as educ_ex
from
t1
left join
t2 on (t1.id = t2.id)
It seems I will have to convert t2 table first before joining, to have a single record on the basis of flag. But I am not sure how to do that.
Please mind the tables are huge and optimized query will be nice.
Please suggest.
You only need to join the first table to the second one, twice:
SELECT t1.Name, t1.address, t1.id, t2a.expense AS Shop_ex, t2b.expense AS Educ_ex
FROM table1 t1
LEFT JOIN table2 t2a
ON t2a.ID = t1.id AND t2a.Flag = 'Shop'
LEFT JOIN table2 t2b
ON t2b.ID = t1.id AND t2b.Flag = 'Educ'
Demo

SQL Server : select from multiple tables and calculate percentages

I have four tables and I would need to extract data from them to calculate the percentage
Table1
ID FK1 FK2
------------------
1 1 1
2 2 2
3 3 3
Table2
ID Name
------------------
1 L1
2 A1
3 B
Table3
ID FK3
------------------
1 1
2 2
3 3
Table4
ID Name
------------------
1 BA
2 N
3 CE
Now I need to get a Name from table4, which will be displayed as individual rows and then a Name from table2, which will be listed as individual columns and the value will then be a percentage of the record from table4:
Name L1 A1 B
---------------------------
BA 20(%) 40(%) 40(%)
N 30(%) 20(%) 30(%)
CE 15(%) 15(%) 70(%)
Because there are links, I'll give an example of what question I have now
select t3.Name
from table1 t1 (nolock)
join table2 t2 (nolock) on t1.FK1 = t2.ID
join table3 t3 (nolock) on t1.FK2 = t3.ID
join table4 t4 (nolock) on t2.FK3 = t4.ID
Does anyone have any idea how to do this? Thank you very much

MS Access Joining Three tables on same field

I have the following tables
t1: t2: t3:
id id f1 id f2
1 1 a 3 a
2 2 b 4 b
3 3 c 5 c
4
5
and I am trying to get the following result
t4:
id f1 f2
1 a
2 b
3 c a
4 b
5 c
I am using the following query
SELECT t1.id, t2.f1, t3.f2
FROM (t1
LEFT JOIN t2 ON t1.id = t2.id) AS a
LEFT JOIN t3 ON t1.id = t3.id
It works but the query takes a while to run. Is there a better way to do this? Thanks
To offer an alternative which doesn't involve additional tables: you could perhaps try structuring the SQL to perform a nested SELECT query such that only tables are joined for each SELECT query, but I doubt that this would offer a drastic improvement over what you have:
SELECT tmp.id, tmp.f1, t3.f2
FROM
(SELECT t1.id, t2.f1 FROM t1 LEFT JOIN t2 ON t1.id = t2.id) AS tmp
LEFT JOIN t3 ON tmp.id = t3.id

Joining tables without nulls

I'm not sure how to explain what I need but here's the data first:
Table 1
District
-1
3
2
1
3
Table 2
ID ID_Name
1 Main 1
2 Main 2
3 Main 3
How do I join the tables so that it looks like this?
District
-1
Main 3
Main 2
Main 1
Main 3
I'm assuming the second column is named Name for this, but you can do it with a COALESCE and a LEFT JOIN:
Select Coalesce(T2.Name, Str(T1.District)) As District
From Table1 T1
Left Join Table2 T2 On T1.District = T2.Id
assuming table 2 have
Table 2
ID col2
1 Main 1
2 Main 2
3 Main 3
you could use a left join
select table1.Distric, table2.col2
from table1
left join table2 on table1.dictrict = t2.ID
order by table2 col2
You can use left join:
Select coalesce(t2.col, t1.District) from table1 t1
left join table2 t2 on t1.District = t2.Id

Query a table using conditions with another table

Hard to make a good title for this (feel free to edit), but hope it will make more sense ..
Say I have the following tables:
t1:
i1 v1
_________
1 bob
2 NULL
3 sam
4 NULL
5 kenny
5 NULL
t2:
i2 v2 item
______________
1 bob prod_1
2 nick prod_2
3 sam prod_3
4 jj prod_4
5 kenny prod_5
5 cartman prod_6
I need to JOIN the tables on t2.i2 = t1.i1 but only where t2.v2 does not exist in t1.v1. So I'm trying to get the following results:
Goal:
i2 v2 item
__________________
2 nick prod_2
4 jj prod_4
5 cartman prod_6
This query below was my first attempt, and it's not working, so I'm trying to find a working and more efficient solution with JOINs.
SELECT * FROM t2
WHERE v2 NOT IN (
SELECT v1 FROM t1 WHERE t2.i2 = t1.i1
)
Your query is fine, although I would use NOT EXISTS:
SELECT dm2.*
FROM web.delete_me2 dm2
WHERE NOT EXISTS (SELECT 1
FROM web.delete_me1 dm1
WHERE dm2.some_int2 = dm1.some_int1 and dm2.some_var2 = dm1.some_var1
);
Although you can write this as a join, this version should be at least as good performance wise. You want an index on web.delete_me1(some_int1, some_var1).
A LEFT JOIN should be enough
select * From t2
left join t1 on t2.i2 = t1.i1 and t1.v1= t2.v2
where t1.i1 is null
SELECT DISTINCT T1.*, T2.*
FROM T1
JOIN T2
ON T1.ID = T2.ID
LEFT JOIN T2 AS T2NO
ON T2NO.NAME = T1.NAME
WHERE T2NO.NAME IS NULL
or try this
SELECT DISTINCT T2.*
FROM T2
JOIN T1
ON T1.ID = T2.ID
LEFT JOIN T1 AS T1NO
ON T1NO.NAME = T2.NAME
WHERE T1NO.NAME IS NULL
Do you need all records from t2 where i2 is in t1 and v2 is not?
If so, you can write this query
select * from t2
where i2 in (select i1 from t1)
and v2 not in (select v1 from t1 where v1 is not null)
for not in to work as we need, v1 shouldn't be null