I am need to join a main table with two feed tables.Table data below:
MainTable
FeedTable
Query I am running is left inner join
Select ID, MT.ColumnA, FT1.ColumnA, FT1.ColumnB, FT2.ColumnA, FT2.ColumnC, FT3.ColumnA, FT3.ColumnD
from MainTable MT
Left Join FeedTable FTI1 on FT1.fk1 = MT.key
Left Join FeedTable FT2 on FT2.fk2 = MT.key
Left Join FeedTable FT3 on FT3.fk3 = MT.key
The output I get is :
The Output I want to get is :
I am assuming left outer join isn't the way to go about this or am I doing the join wrong?
You want the tables in the wrong order. The FeedTable should be first:
Select ft.*, mt1.key as cola, mt2.key as colb, mt3.key colc
from FeedTable ft left join
MainTable mt1
on ft.fk1 = mt1.key left join
MainTable mt2
on ft.fk2 = mt2.key left join
MainTable mt2
on ft.fk3 = mt3.key;
Related
I have a bigquery table which is a result of multiple left join tables.
The results are duplicated because of the left join (cartesian product)
How do I de-duplicate the rows so I only see one record?
SELECT T1.Col1,T1.Col2,........
T2.Col1,T2.Col2,........
T3.Col1,T3.Col3,........
T5.Col1,T5.Col2,........
T7.Col1.......
FROM `TABLE1` as T1
LEFT JOIN
`TABLE`as T2 ON T1.CUSTOMER_CODE = T2.CUSTOMER_CODE
LEFT JOIN
`TABLE3` as T3 ON (T1.MIAL_CODE) = T3.MIAL_CODE
LEFT JOIN
`TABLE5` as T5
ON T1.WORK_CODE = T5.WORK_CODE
LEFT JOIN
`TABLE7` as T7
ON T1.CA_DATE = T7.date
ORDER BY CA_DATE
Use DISTINCT:
select distinct *
from mytable
or create a new table:
create or replace table my_new_table
as
select distinct *
from mytable
I used GROUP BY and it worked fine to get rid of duplicates
SELECT T1.Col1,T1.Col2,........
T2.Col1,T2.Col2,........
T3.Col1,T3.Col3,........
T5.Col1,T5.Col2,........
T7.Col1.......
FROM `TABLE1` as T1
LEFT JOIN
`TABLE`as T2 ON T1.CUSTOMER_CODE = T2.CUSTOMER_CODE
LEFT JOIN
`TABLE3` as T3 ON (T1.MIAL_CODE) = T3.MIAL_CODE
LEFT JOIN
`TABLE5` as T5
ON T1.WORK_CODE = T5.WORK_CODE
LEFT JOIN
`TABLE7` as T7
ON T1.CA_DATE = T7.date
GROUP BY T1.Col1,T1.Col2,........
T2.Col1,T2.Col2,........
T3.Col1,T3.Col3,........
T5.Col1,T5.Col2,........
T7.Col1.......
ORDER BY CA_DATE
I set the THEATRES size using THEATRES.NUMOFROWS, THEATRES.NUMOFCOLS and each SEAT.SEATNO is tied to THEATRES.ID and SHOWTIMES.ID is tied to THEATRES.ID and TICKET_ITEMS are tied to SHOWTIMES.ID
I want to display all the values by joining the table using where clause for showtime.id. I know outer join will display null on non-matching but my query only shows one records.
SELECT
SHOWTIMES.ID AS SHOWTIMESID,
SHOWTIMES.THEATREID,
THEATRES.THEATRENAME,
THEATRES.NUMOFROWS,
THEATRES.NUMOFCOLS,
SEAT.SEATNO AS SEATLABEL,
SEAT.ROWID,
SEAT.COLUMNID,
TICKET_ITEMS.SEATNO,
TICKET_ITEMS.TICKETCODE
FROM
SHOWTIMES FULL OUTER JOIN TICKET_ITEMS ON SHOWTIMES.ID =TICKET_ITEMS.SHOWTIMESID
FULL OUTER JOIN THEATRES ON SHOWTIMES.THEATREID = THEATRES.ID
FULL OUTER JOIN SEAT ON SEAT.SEATNO = TICKET_ITEMS.SEATNO
WHERE
SHOWTIMES.ID = 1
;
If you are using any kind of OUTER JOIN and you refer to a column in the WHERE you need to handle NULLs. If you don't, you turn the JOIN into an implicit INNER JOIN. Take this simple example:
WITH T1 AS(
SELECT ID, SomeString
FROM (VALUES(1,'abc'),(2,'def')) V(ID, SomeString)),
T2 AS(
SELECT ID, fID, AnotherString
FROM (VALUES(1,1,'asd'),(2,1,'asdased')) V(ID, fID, AnotherString))
SELECT *
FROM T1
LEFT JOIN T2 ON T1.ID = T2.ID
WHERE T2.AnotherString = 'asd';
You might expect to get 2 rows here, one for where T1.ID is 1 with a joined row and 1 for T1.ID is 2, but with no joined rows. That isn't the case due to the WHERE. The correct solution here would be to move the WHERE to the ON:
WITH T1 AS(
SELECT ID, SomeString
FROM (VALUES(1,'abc'),(2,'def')) V(ID, SomeString)),
T2 AS(
SELECT ID, fID, AnotherString
FROM (VALUES(1,1,'asd'),(2,1,'asdased')) V(ID, fID, AnotherString))
SELECT *
FROM T1
LEFT JOIN T2 ON T1.ID = T2.ID
AND T2.AnotherString = 'asd';
With what you have, you can't do that, as you're using the base table, thus you'll need handle the NULL by changing your WHERE to:
WHERE SHOWTIMES.ID = 1 OR SHOWTIMES.ID IS NULL;
I imagine that your database has proper foreign key relationships set up -- so the theater id in one table is a valid id.
If so, you don't need full join. In fact, it is very rarely needed. I suspect that inner joins are sufficient (but that is the results you are getting).
If you want all theaters with the appropriate shows -- if any -- then use left join and start with the theaters:
select st.ID AS SHOWTIMESID, st.THEATREID,
th.THEATRENAME, th.NUMOFROWS, th.NUMOFCOLS,
s.SEATNO AS SEATLABEL, s.ROWID, s.COLUMNID,
ti.SEATNO, ti.TICKETCODE
from theatres th left join
showtimes st
on st.theatreid = th.id and st.id = 1 left join
ticket_items ti
on st.ID =ti.showtimesid left join
seat s
on s.seatno = ti.seatno
I am trying to join 7 tables and insert the joined data into one big joined table, to do this I am using the query below
INSERT OVERWRITE TABLE databaseName.joinTab PARTITION (tran_date)
SELECT <180 cols across all 7 tables>
FROM databaseName.table1 tab1
LEFT OUTER JOIN databaseName.table2 tab2 ON (tab1.id = tab2.id and
tab1.tran_date='20171030' and tab2.tran_date='20171030')
LEFT OUTER JOIN databaseName.table3 tab3 ON (tab1.id = tab3.id and
tab1.tran_date='20171030' and tab3.tran_date='20171030')
LEFT OUTER JOIN databaseName.table4 tab4 ON (tab1.id = tab4.id and
tab1.tran_date='20171030' and tab4.tran_date='20171030')
LEFT OUTER JOIN databaseName.table5 tab5 ON (tab1.id = tab5.id and
tab1.tran_date='20171030' and tab5.tran_date='20171030')
LEFT OUTER JOIN databaseName.table6 tab6 ON (tab1.id = tab6.id and
tab1.tran_date='20171030' and tab6.tran_date='20171030')
LEFT OUTER JOIN databaseName.table7 tab7 ON (tab1.id = tab7.id and
tab1.tran_date='20171030' and tab7.tran_date='20171030')
WHERE (tab1.tran_date='20171030');
tran_date is the partition column for all of these tables, the reason that i have a where clause as well as the condition being in the ON statement is that i was finding that the tez job started would do a full table scan for table1 if i didnt.
So my issue here is if i do a count(*) from table1 on tran_date=20171030 then i get 11845917 as the result
If i do a count(*) from the new joined table(joinTab) for that same partition tran_date=20171030 I only get the result 97609 which is a very large difference, as i'm using left outer joins i had thought that it should move all the data from table1 into the join table and populate nulls for anything not in the other tables. I should mention tran_date in joinTab is derived from when table1 data is loaded
Is there anything here that doesn't look right?
Thanks for your help
Dan
I couldn't test if this solution works because you haven't provided a reproducible example, but you can try something like this:
WITH tab1_temp AS (SELECT <tab1 cols> WHERE tab1.tran_date='20171030'
)
INSERT OVERWRITE TABLE databaseName.joinTab PARTITION (tran_date)
SELECT <180 cols across all 7 tables>
FROM tab1_temp
LEFT OUTER JOIN databaseName.table2 tab2 ON (tab1.id = tab2.id and
tab1.tran_date='20171030' and tab2.tran_date='20171030')
LEFT OUTER JOIN databaseName.table3 tab3 ON (tab1.id = tab3.id and
tab1.tran_date='20171030' and tab3.tran_date='20171030')
LEFT OUTER JOIN databaseName.table4 tab4 ON (tab1.id = tab4.id and
tab1.tran_date='20171030' and tab4.tran_date='20171030')
LEFT OUTER JOIN databaseName.table5 tab5 ON (tab1.id = tab5.id and
tab1.tran_date='20171030' and tab5.tran_date='20171030')
LEFT OUTER JOIN databaseName.table6 tab6 ON (tab1.id = tab6.id and
tab1.tran_date='20171030' and tab6.tran_date='20171030')
LEFT OUTER JOIN databaseName.table7 tab7 ON (tab1.id = tab7.id and
tab1.tran_date='20171030' and tab7.tran_date='20171030')
;
I need all my records from T3 Table in below query.
how can I use left join statement to solve my problem in oracle.
SELECT COUNT(*)
FROM R
LEFT JOIN RD
ON (R.ID = RD.RES_INFO_ID)
LEFT JOIN RES
ON (R.SEL_EVL_RES_ID = RES.ID)
LEFT JOIN S
ON (S.ID = R.SEL_EVL_ID)
LEFT JOIN D
ON (RD.DEC_DET_ID = D.ID)
LEFT JOIN M
ON (S.EVL_MAS_ID = M.ID)
LEFT JOIN P_RES
ON (P_RES.PRS_ID = RES.PRS_ID)
LEFT JOIN P_MAS
ON (P_MAS.PRS_ID = M.PRS_ID)
LEFT JOIN P_EVL
ON (P_EVL.PRS_ID = S.PRS_ID)
LEFT JOIN P
ON (P.EVL_MAS_ID = M.ID)
LEFT JOIN DM
ON (DM.EVL_RES_INF_DET_ID = RD.ID);
Thanks in advance
If you need all records from T3, then that should be the first table in the FROM clause. All the joins should be LEFT JOINs. I presume you intend:
SELECT COUNT(*)
FROM T3 R LEFT JOIN
T1 S
ON S.ID = R.SELF_EVALUATION_ID LEFT JOIN
T2 RD
ON RD.EVL_RESOURCE_INFO_ID = R.ID LEFT JOIN
T4 RES
ON R.SELF_EVALUATION_RESOURCE_IDRES.ID LEFT JOIN
T5 M
ON S.EVALUATION_MASTER_ID = M.ID LEFT JOIN
T6 D
ON RD.DECENCY_DETAIL_ID = D.ID LEFT JOIN
T7 P
ON P.EVALUATION_MASTER_ID = M.ID LEFT JOIN
T8 DM
ON DM.EVL_RES_INFO_DETAIL_ID = RD.ID;
In the future, follow a simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax with the join conditions in the ON clause.
I have the following query
Select TA.Column1 , COALESCE(TE.Column2,TA.Column2) as Mydata
from TableA TA
INNER JOIN TableB TB ON (TA.Column2 =TB.Column1)
LEFT JOIN TableC TC ON (TB.Column2 = TC.Column1)
LEFT JOIN TableD TD ON (TC.Column1 = TD.Column1)
LEFT JOIN TableE TE ON(TD.Column2 = TE.Column1)
To get the result I am looking for I need to Join the MyData column with another TableX
e.g INNER JOIN TableX TX ON (TableX.Column1 = MyData) and have TableX.COlumn2 in my select query .
My query is how can I join the COALESCE(TE.Column2,TA.Column2) as Mydata fetched value with a table TableX
On the surface, you should be able to do this. (Did you try that already?)
Select TA.Column1 , COALESCE(TE.Column2,TA.Column2) as Mydata, TX.Column2
from TableA TA
INNER JOIN TableB TB ON (TA.Column2 =TB.Column1)
LEFT JOIN TableC TC ON (TB.Column2 = TC.Column1)
LEFT JOIN TableD TD ON (TC.Column1 = TD.Column1)
LEFT JOIN TableE TE ON(TD.Column2 = TE.Column1)
LEFT JOIN TableX TX ON (COALESCE(TE.Column2,TA.Column2)) = TX.Column1