Inner join of 2 tables with the same ID - mysql

I have a table(T1) in which 2 columns(X and Y) are id's. The name's of these corresponding id's are in another table (T2) with the column name.
Suppose I was only using X then, a simple Inner join would have solved my problem in getting the name.
Such as
Select T1.somedata,T1.somedata1,T2.name from T1
Inner Join T2 ON T1.X=T2.id
But,what if I want the name's to be resolved for the T1.Y also?, which name would the Inner Join resolve it to ??
Select T1.somedata,T1.somedata1,T2.name from T1
Inner Join T2 ON T1.X=T2.id
Inner Join T2 ON T1.Y=T2.id
The above query is wrong, I know. Can I get the names of those corresponding to both T1.Xand T1.Y with an INNER Join?
-Beginner

I suggest always add aliases to tables and columns. So you will be sure which data are selected.
select
T1.somedata,
T1.somedata1,
T2X.name as XName,
T2Y.name as YName
from T1 as T1
inner join T2 as T2X on T2X.id = T1.X
inner join T2 as T2Y on T2Y.id = T1.Y

This selects both names as separate columns:
Select T1.somedata,T1.somedata1,T2a.name, T2b.name
from T1
Inner Join T2 as T2a ON T1.X=T2a.id
Inner Join T2 as T2b ON T1.Y=T2b.id
The following would generate two records in the result set:
Select T1.somedata, T1.somedata1, T2.name
from T1
Inner Join T2 ON T1.X=T2.id Or T1.Y=T2.id

you need to join table T2 twice and supply aliases on the names to avoid ambiguity.
SELECT a.*,
b.name as NameB,
c.name as NameC
FROM T1 a
INNER JOIN T2 b
ON a.x = b.id
INNER JOIN T2 c
On a.y = c.id

You need to join table T2 twice and supply aliases on the names to avoid ambiguity.
SELECT a.*,
b.name as NameB,
c.name as NameC
FROM T1 a
INNER JOIN T2 b
ON a.x = b.id
INNER JOIN T2 c
On a.y = c.id

Related

How in inner join few table consecutively in single sql [duplicate]

This question already has answers here:
Joining three tables using MySQL
(11 answers)
Closed 3 years ago.
i am currently have few 5 table , and i wan to inner join table 1 to table 2, and then table to 2 to table 3, and so on....
i have tried this with few separated inner join, but how to get the same result with only 1 sql
SELECT table1.CW_S_EVT,table2.CW_S_TYP, table2.CW_S_SERVER
FROM table1 INNER JOIN table2
ON table1.CW_S_EVT = table2.CW_S_EVT;
SELECT table2.CW_S_EVT,table2.CW_S_TYP, table3.CW_S_TPL
FROM table2 INNER JOIN table3
ON table2 .CW_S_TYP = table3.CW_S_TYP
SELECT table3.CW_S_TPL, table4.CW_L_TPL,table4.CW_CONTENT
FROM table3 INNER JOIN table4
ON table3.CW_S_TPL = table4.CW_S_TPL
SELECT table1.CW_S_EVT,table5.CW_S_VAR, table5.CW_L_VAR
FROM table1 INNER JOIN table5
ON table1.CW_S_EVT = table5.CW_S_EVT;
This is the code i found on internet but it does not match my case.
SELECT *
FROM table1
INNER JOIN table2
ON table1.primaryKey=table2.table1Id
INNER JOIN table3
ON table1.primaryKey=table3.table1Id
What you need is a left join your tables on your criteria. Since this will result to null values, adding coalesce function will be able to help us give those values that matches your criteria.
Additional distinct keyword if its needed.
SELECT distinct coalesce(table1.CW_S_EVT, table2.CW_S_EVT, table3.CW_S_TPL)
, coalesce(table2.CW_S_TYP, table4.CW_L_TPL, table5.CW_S_VAR)
, coalesce(table2.CW_S_SERVER, table3.CW_S_TPL, table4.CW_CONTENT, table5.CW_L_VAR)
FROM table1
LEFT JOIN table2 ON table1.CW_S_EVT = table2.CW_S_EVT;
LEFT JOIN table3 ON table2.CW_S_TYP = table3.CW_S_TYP
LEFT JOIN table4 ON table3.CW_S_TPL = table4.CW_S_TPL
LEFT JOIN table5 ON table1.CW_S_EVT = table5.CW_S_EVT;
Try this
SELECT
table1.CW_S_EVT as t1_CW_S_EVT,
table2.CW_S_TYP as t2_CW_S_TY,
table2.CW_S_SERVE as t2_CW_S_SERVE,
table2.CW_S_EVT as t2_CW_S_EVT,
table3.CW_S_TPL as t3_CW_S_TPL,
table4.CW_L_TPL as t4_CW_L_TPL,
table4.CW_CONTENT as t4_CW_CONTENT,
table5.CW_S_VAR as t5_CW_S_VAR,
table5.CW_L_VAR as t5_CW_L_VAR
FROM
table1, table2, table3, table4, table5
where
table1.CW_S_EVT = table2.CW_S_EVT AND
table2 .CW_S_TYP = table3.CW_S_TYP AND
table3.CW_S_TPL = table4.CW_S_TPL AND
table1.CW_S_EVT = table5.CW_S_EVT;
SELECT table1.CW_S_EVT,table3.CW_S_TYP,table4.CW_S_TPL, table5.CW_S_VAR
FROM table1
INNER JOIN table2 ON table1.CW_S_EVT = table2.CW_S_EVT
INNER JOIN table3 ON table2.CW_S_TYP = table3.CW_S_TYP
INNER JOIN table4 ON table3.CW_S_TPL = table4.CW_S_TPL
INNER JOIN table5 ON table1.CW_S_EVT = table5.CW_S_EVT
Thanks for all the kind answer, but i found this working at last, juz record here maybe for future use.^^

MySQL : Using alias inside a join condition

SELECT t1.*, IFNULL(t2.profile_id, t3.profile_id) AS `profile_id`
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.id = t2.some_coulmn
LEFT JOIN table3 AS t3
ON t1.id = t3.some_coulmn
LEFT JOIN table4 AS t4
ON profile_id = t4.some_column
I'm trying to use an alias (profile_id) inside my join condition. It fails. Is there a way to do this?
Column aliases defined in th SELECT clause cannot be used in the join conditions. This is because the FROM clause is evaluated before the SELECT clause.
If I followed you correctly, you probably want:
SELECT t1.*, IFNULL(t2.profile_id, t3.profile_id) AS `profile_id`
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.id = t2.some_coulm
LEFT JOIN table3 AS t3
ON t1.id = t3.some_coulm
LEFT JOIN table4 AS t4
ON IFNULL(t2.profile_id, t3.profile_id) = t4.some_column

MySQL How to do a 3 table join

I'm trying to perform a 3 table join on MySQL in order to achieve something like the diagram below.
The main problem I'm having is that I only want to work with the records of table A which has 100 records so if there are no relationships for the right tables I would like to see a null.
This all works fine when only table A and B are involved but when I try to do the third join with C I'm getting more than the original 100 records, I'm getting 130 which I believe is because is adding the records that match B-C with duplicate data from table A.
What am I missing?
This is the SQL I currently have that returns correctly 100 records
SELECT count(A.id)
FROM tableA A
LEFT JOIN TableB B ON B.id = A.b_id
This is what I'm trying to do that is returning more than the original 100 records for Table A.
SELECT count(A.id)
FROM tableA A
LEFT JOIN TableB B ON B.id = A.b_id
LEFT JOIN TableC C ON C.id = B.c_id
This could be resolved by a JOIN to a subquery rather than a table.
If you had unique Ids to join to, it would simply be like you've tried already (arbitrary example):
SELECT * from table1 t1
LEFT JOIN table2 t2 on t2.id = t1.id
LEFT JOIN table3 t3 on t3.id = t2.id
If, however the id field in table3 wasn't unique, you'd get multiple rows for each duplicate. You could resolve this by:
SELECT * from table1 t1
LEFT JOIN table2 t2 on t2.id = t1.id
LEFT JOIN (SELECT * FROM table3 GROUP BY id) t3 on t3.id = t2.id
So, using your example (assuming only the third join has duplicates), something like:
SELECT count(A.id)
FROM tableA A
LEFT JOIN TableB B ON B.id = A.b_id
LEFT JOIN (SELECT * FROM TableC GROUP BY id) C ON C.id = B.c_id
...should do the trick. This is down to assumption of your table and data structure, so you might want to make the asterisk more explicit.
SELECT count(distinct A.id)
FROM tableA A
LEFT JOIN TableB B ON B.id = A.b_id
LEFT JOIN TableC C ON C.id = B.c_id

Transforming queries: right joins to left joins

Suppose I have following tables: T1,T2 and T3.
How could I rephrase the following query using only left joins.
Select *
From T1
Right join T2 On T1.FK2=T2.PK
Right join T3 On T1.FK3=T3.PK
Following attempt is not correct:
Select *
From T2
Left join T1 On T1.FK2=T2.PK
Left join T3 On T1.FK3=T3.PK
T3 is On the wrong Side of the join. Is the following possible:
Select *
From T2
Left join T3 On T1.FK3=T3.PK
Left join T1 On T1.FK2=T2.PK
I can't Find a way to put both tables 2 and 3 On the left Side of 1 and use the correspondent fields to join all tables? The last query uses fields of table 1 before this table is mentioned in the query.
Or something like this?
Select *
From T2
Left join (
T3 left join T1
On T1.FK3=T3.PK)
On T1.FK2=T2.PK
Apparently brackets can help to order your joins. I wonder if this is really documented, i've found Nothing at first glance in the mysql docs.
Following query is correct and does not have any subqueries:
Select T1.Id Ida, t2.id idb, T3.id idc FROM T3
LEFT JOIN
(T2
LEFT JOIN T1 ON (T1.ID = T2.ID))
ON (T1.ID= T3.ID);
You need to use a subquery to first join t1 with t2 and then join the result with t3:
SELECT T.ID1 ID1, T.ID2 ID2, T3.ID ID3 FROM T3
LEFT JOIN
(SELECT T1.ID ID1, T2.ID ID2 FROM T2
LEFT JOIN T1 ON (T1.ID = T2.ID)) T
ON (T.ID1 = T3.ID);
SQL Fiddle
The first way is just to reverse the order that the tables are mentioned:
Select *
from t3 left outer join
t2
on T1.FK3 = T3.PK left outer join
t1
on T1.FK2 = T2.PK
But this won't work, because the first condition is on t1 and not t2. And t2 hasn't yet been defined.
When working with chains of tables in left or right outer joins, only the first (or last) tables are important, because they "drive" the query. "Drive" in the sense that they provide all the values even when there are no matches. So, the following should do what you want:
Select *
from t3 left outer join
t1
on T1.FK3 = T3.PK left outer join
t2
on T1.FK2 = T2.PK;

select from 2 tables with for statement in sql

i have 2 table and want to select data from them
table 1 :
id
name
table 2
id
name
table1.id
and i want a query to make this resualt:
table1.id
table1.name
count(table2.id)
this is simple and solved by this way :
SELECT
c.id as corridor_id,
c.name as corridor_name,
(SELECT COUNT( r.id ) FROM rooms AS r WHERE r.corridorid = c.id ) as room_count
FROM corridors AS c
now if i add another table like this :
table3
id
name
table2.id
and want a query like this :
table1.id
table1.name
count(table2.id)
count(table3.id)
idk how can i do such as this query, but if there is a way i'll be happy to find it, many tnx
You'll want to join them all together, and then Group them along these lines:
SELECT
t1.Id,
t1.Name,
Count(t2.Id) AS T2Count,
Count(t3.Id) AS T3Count
FROM table1 t1
JOIN table2 t2
ON t1.Id = t2.table1_id
JOIN table3 t3
ON t2.id = t3.table2_id
GROUP BY t1.Id, t1.Name
You don't need nested SELECT statement here. You can do it by grouping and to avoid double-counting you would want DISTINCT keyword:
SELECT
c.id as corridor_id,
c.name as corridor_name,
COUNT(DISTINCT r1.id),
COUNT(DISTINCT r2.id)
FROM
corridors c
JOIN rooms r ON r.corridorid = c.id
JOIN rooms2 r2 ON r2.corridorid = c.id
GROUP BY c.id
If you want to properly treat missing values (0 counts) you can also do this:
SELECT
c.id as corridor_id,
c.name as corridor_name,
IFNULL(COUNT(DISTINCT r1.id), 0),
IFNULL(COUNT(DISTINCT r2.id), 0)
FROM
corridors c
LEFT JOIN rooms r ON r.corridorid = c.id
LEFT JOIN rooms2 r2 ON r2.corridorid = c.id
GROUP BY c.id