Consolidating 5 Queries into One - sql

I have two pieces of data that I have analysed and found five distinct ways in which the data is linked. Is it possible to combine these into one query? Combining queries like these is outside my skill set, but getting these queries into a singular one would be a huge help for what I am trying to accomplish.
Here are the queries (Actual Table and Column names have been replaced)
SELECT a.Col1, d.Col2 FROM Table1 A
RIGHT JOIN Table2 B ON A.Col1=B.Col3
LEFT JOIN Table3 C ON B.Col4=C.Col5
LEFT JOIN Table4 D ON D.Col2=C.Col6;
SELECT a.Col1, d.Col2 FROM Table1 A
RIGHT JOIN Table2 B ON A.Col1=B.Col3
LEFT JOIN Table5 E ON E.Col14=B.Col4 AND Col7='Value1'
LEFT JOIN Table6 F ON E.Col8=F.Col9
LEFT JOIN Table3 C ON F.Col9=C.Col5
LEFT JOIN Table4 D ON D.Col2=C.Col6 ;
SELECT a.Col1, d.Col2 FROM Table1 A
RIGHT JOIN Table2 B ON A.Col1=B.Col3
LEFT JOIN Table7 E ON E.Col10=B.Col4 AND Col7='Value2'
LEFT JOIN Table6 F ON E.Col11=F.Col9
LEFT JOIN Table3 C ON F.Col9=C.Col5
LEFT JOIN Table4 D ON D.Col2=C.Col6 C;
SELECT a.Col1, d.Col2 FROM Table1 A
RIGHT JOIN Table2 B ON A.Col1=B.Col3
LEFT JOIN Table7 F ON F.Col10=b.Col4 AND Col7='Value3'
LEFT JOIN Table3 C ON F.Col11=C.Col5
LEFT JOIN Table4 D ON D.Col2=C.Col6 ;
SELECT a.Col1, d.Col2 FROM Table1 A
RIGHT JOIN Table2 B ON A.Col1=B.Col3
LEFT JOIN Table8 E ON E.Col12=B.Col4 AND Col7='Value4'
LEFT JOIN Table6 F ON E.Col13=F.Col9
LEFT JOIN Table3 C ON F.Col9=C.Col5
LEFT JOIN Table4 D ON D.Col2=C.Col6 ;
The result of the queries should give data like below. For any value in Col1 there could be multiple values in Col2, however, for each Col1/Col2 pairing, only 1 set of the queries above creates the link between the two entities.
Col1 | Col2
-----------
1 | A
2 | B
2 | C
3 | D
4 | A
Thank you for any assistance. Let me know if have any questions on the queries or results.
Note - These queries are being executed against an Oracle database.

Use:
SELECT a.Col1, d.Col2
FROM Table2 B
LEFT JOIN Table1 A ON A.Col1=B.Col3
LEFT JOIN Table5 H ON H.Col14=B.Col4 AND Col7='Value1'
LEFT JOIN Table7 E ON (E.Col10=B.Col4 AND Col7='Value2') OR (F.Col10=b.Col4 AND Col7='Value3')
LEFT JOIN Table6 F ON (E.Col13=F.Col9) OR (E.Col8=F.Col9) OR (E.Col11=F.Col9) OR (H.Col8=F.Col9)
LEFT JOIN Table3 C ON (B.Col4=C.Col5) OR (F.Col9=C.Col5) OR (F.Col11=C.Col5)
LEFT JOIN Table4 D ON D.Col2=C.Col6;
or a UNION operator for your select statements.

Related

SQL Left Join Efficiency in Presto/Spark SQL

I will like to ask which will be the better option and why if I intend to LEFT JOIN a few tables? Provide an example below.
Option 1:
SELECT * FROM TABLEA a
LEFT JOIN TABLEB b
ON a.id=b.id
LEFT JOIN TABLEC c
ON a.id=c.id
LEFT JOIN TABLED d
ON a.id=d.id
Option 2(CTE):
WITH tablea_b as (
SELECT * FROM TABLEA a
LEFT JOIN TABLEB b
ON a.id=b.id)
, tablea_b_c as (
SELECT * FROM tablea_b a
LEFT JOIN TABLEC c
ON a.id=c.id)
, tablea_b_c_d as (
SELECT * FROM tablea_b_c a
LEFT JOIN TABLED d
ON a.id = d.id) SELECT * FROM tablea_b_c_d
Basically the differences is i left join part by part at option 2 whereas at option 1 i do it in one go. Are there any differences in terms of efficiency?

What is the difference between specifying 'ON' at a join and after all the joins?

I came across a code which joins two tables and on specifies the link (the 'ON' clause) between the three tables at the end.
The code was written like this:
SELECT *
FROM tb1 AS a
LEFT OUTER JOIN tbl2 AS b
LEFT OUTER JOIN tbl3 AS c
ON b.ColA = c.ColA ON a.ColA = b.ColA
The result of this was different from when I changed it to:
SELECT *
FROM tb1 AS a
LEFT OUTER JOIN tbl2 AS b ON a.ColA = b.ColA
LEFT OUTER JOIN tbl3 AS c ON b.ColA = c.ColA
Could someone please explain the difference between these two joins?
I am surprised that the two queries yield different results, as they look logically equivalent to me. As another answer has pointed out, this is logically equivalent to the following query (but without duplicate column errors):
SELECT *
FROM tb1 AS a
LEFT OUTER JOIN
( SELECT *
FROM tbl2 AS b
LEFT OUTER JOIN tbl3 AS c
ON b.ColA = c.ColA
) AS b
ON a.ColA = b.ColA
i.e. it changes the order of operations, tbl2 is joined to tbl3, first, then the result of that query is joined with tb1. This is typically more usefull when you need to INNER JOIN on a table that is already part of an OUTER JOIN. For example, if you only wanted to return records from tbl2 where the corresponding entry was in tbl3, you couldn't change the original query to this:
SELECT *
FROM tb1 AS a
LEFT OUTER JOIN tbl2 AS b ON a.ColA = b.ColA
INNER JOIN tbl3 AS c ON b.ColA = c.ColA
As this would also remove any records from tb1 with no corresponding entry in tbl2, whereas if you wrote it like this:
SELECT *
FROM tb1 AS a
LEFT OUTER JOIN tbl2 AS b
INNER JOIN tbl3 AS c
ON b.ColA = c.ColA ON a.ColA = b.ColA
This is where the difference is more noticable. The latter is equivalent to this:
SELECT *
FROM tb1 AS a
LEFT OUTER JOIN
( SELECT *
FROM tbl2 AS b
INNER JOIN tbl3 AS c
ON b.ColA = c.ColA
) AS b
ON a.ColA = b.ColA
Which would correctly remove any records from tbl2 where there was no corresponding record in tbl3, but retain records from tbl1 that have no corresponding record in the resulting dataset of tbl2 and tbl3.
SAMPLE SCHEMA AND QUERIES
DECLARE #T1 TABLE (ColA INT);
DECLARE #T2 TABLE (ColA INT);
DECLARE #T3 TABLE (ColA INT);
INSERT #T1 (ColA) VALUES (1), (2), (3);
INSERT #T2 (ColA) VALUES (1), (2);
INSERT #T3 (ColA) VALUES (1);
-- query 1
SELECT *
FROM #T1 AS a
LEFT OUTER JOIN #T2 AS b ON a.ColA = b.ColA
LEFT OUTER JOIN #T3 AS c ON b.ColA = c.ColA;
-- query 2
SELECT *
FROM #T1 AS a
LEFT OUTER JOIN #T2 AS b
LEFT OUTER JOIN #T3 AS c
ON b.ColA = c.ColA ON a.ColA = b.ColA;
-- query 3
SELECT *
FROM #T1 AS a
LEFT OUTER JOIN #T2 AS b ON a.ColA = b.ColA
INNER JOIN #T3 AS c ON b.ColA = c.ColA;
-- query 4
SELECT *
FROM #T1 AS a
LEFT OUTER JOIN #T2 AS b
INNER JOIN #T3 AS c
ON b.ColA = c.ColA ON a.ColA = b.ColA
RESULTS
-- QUERY 1 & 2
T1.ColA T2.ColA T3.ColA
----------------------------------
1 1 1
2 2 NULL
3 NULL NULL
-- QUERY 3
T1.ColA T2.ColA T3.ColA
----------------------------------
1 1 1
-- QUERY 4
T1.ColA T2.ColA T3.ColA
----------------------------------
1 1 1
2 NULL NULL
3 NULL NULL
Your first query is evaluated like the following
SELECT *
FROM tb1 AS a
LEFT OUTER JOIN
(
SELECT *
FROM tbl2 AS b
LEFT OUTER JOIN tbl3 AS c
ON b.ColA = c.ColA
) AS temp
ON a.ColA = temp.ColA
Which is not logically same as your second query. That's why, you are getting different result.
If you used INNER JOIN instead of LEFT OUTER JOIN you would get same result for both queries.
N.B: the above query will give you error because tbl2 and tbl3 both have a column with same name. so you may need to alias that to execute the above query properly.
Please note that the database is free to decide in which order to process the tables. So especially oracle will change the query to its liking upon its internal statistics. Ofcourse only in a way that leads logically to the same results.
Putting the on clause directly to the tables to be joined makes it more readle.
So my recommendation is to do
tb1 left out join tbl23 on tb1.xxx=tb2.yyy

Oracle SQL - left join + left outer join

I am querying three tables. TABLE1 A and TABLE2 B have a one-to-one ratio on DEPTID. TABLE3 C, however, does not hold 0 values. I can successfully get COUNT to give me 0 values from TABLE3 C when doing a LEFT OUTER JOIN with TABLE1 A or TABLE2 B, but it gives me (null) instead of 0 when I join all three tables together. I need it to return 0 instead of (null). Any help is very much appreciated:
SELECT A.DEPTID, B.DEPT_NAME, SUM(C.HEAD_COUNT)
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.DEPTID = B.DEPTID
LEFT OUTER JOIN TABLE3 C ON A.POSITION_NUMBER = C.POSITION_NUMBER
GROUP BY A.DEPTID, B.DEPT_NAME
Here is what I am currently getting:
Dept 1: headcount 9
Dept 2: headcount 11
Dept 3: (null)
Use COALESCE() or NVL() to substitute 0 for NULL values:
SELECT A.DEPTID,
B.DEPT_NAME,
SUM(COALESCE( C.HEAD_COUNT, 0 ) )
FROM TABLE1 A
LEFT OUTER JOIN TABLE2 B
ON A.DEPTID = B.DEPTID
LEFT OUTER JOIN TABLE3 C
ON A.POSITION_NUMBER = C.POSITION_NUMBER
GROUP BY A.DEPTID,
B.DEPT_NAME

Adding more joins to a select

I am having some trouble trying to add 2 more joins to a select. The bellow works for me:
FROM
TABLE1 A
INNER JOIN TABLE2 B ON A.ID = B.ID
LEFT JOIN TABLE3 C ON A.REQUESTED_BY = C.USER_NAME
LEFT JOIN TABLE3 D ON A.COORDINATOR = D.USER_NAME
INNER JOIN TABLE4 E ON A.ID = E.PARENT_ID
INNER JOIN TABLE5 F ON E.ID = F.ID
But I need to get more information, so I tried something like this (added the last 2 rows):
FROM
TABLE1 A
INNER JOIN TABLE2 B ON A.ID = B.ID
LEFT JOIN TABLE3 C ON A.REQUESTED_BY = C.USER_NAME
LEFT JOIN TABLE3 D ON A.COORDINATOR = D.USER_NAME
INNER JOIN TABLE4 E ON A.ID = E.PARENT_ID
INNER JOIN TABLE5 F ON E.ID = F.ID
INNER JOIN TABLE6 G ON A.ID = B.ID
LEFT JOIN TABLE3 H ON G.COORDINATOR = H.USER_NAME
And this isn't working like it should.
Question: How can I add the last two joins to make the select works? Thanks.
You're not actually joining to TABLE6 (G) anywhere. I would think that this join:
INNER JOIN TABLE6 G ON A.ID = B.ID
should be something like this instead:
INNER JOIN TABLE6 G ON A.ID = G.ID
And as a side note, I hope you're using table aliases that are more meaningful than A, B, C, etc. in your real code. ;-)

Joining on multiple tables in teradata

Please help me through this
sel a.col1,a.co2,a.col3,.........b.col1,b.col2..,c.col1,c.col2
from table1 as a inner join table2 as b on a.col1 =b.col1
inner join table3 as c on a.col1 = b.col1
where col1 = xxxxx;
Now i need join one more table table4. As table4 dont have col1 as primary index in it I need to join this to another table which has Primary key.
The below is the different query which i need inculde this in to the above sel statement.
Sel xx.col1,yy.aaa,yy.bbb,zz.ccc,zz.ddd,zz.eee
from tablea as xx, tableb as yy, table4 as zz
where xx.col1 = yy.bbb and yy.aaa = zz.ccc
Primary indexs :
col1 for table1,table2,table3,tablexx
aaa for tableb
ccc for table4
Thanks in advance
How about:
Select a.leg,c.btn,p.prods,svc.sr,speed.test, a.leg, b.acct_id, e.emp_no, e.emp_name
FROM db1.tb1 as a
inner join db1.tb2 as C ON a.leg = C.leg
inner join db1.tb3 as p ON a.leg = p.leg
inner join db1.tb3 as svc on a.leg = svc.leg
inner join db2.tb4 as speed on a.leg = speed.leg
inner join db4.tb1 as b on a.leg = b.sce_acct_id
inner join db4.tb5 as e on b.acct_id = e.acct_id
where a.leg ='xxxx'