BiqQuery Left Outer with an OR condition Error - google-bigquery

Ran into the BigQuery limitation that you can't use an OR on a JOIN. Runs fine in Oracle.
Looking for some hints on how to accomplish this in another matter.
The last left outer join produces this error.
LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.
select [col list]
from tablea a
left outer join tableb b on a.id = b.ID
left outer join tabled d on a.id = d.iid
left outer join tablee e on b.id = e.pid and b.cid = e.id
left outer join tablef f on d.runitid = f.id or e.runitid = f.id

Due to additional join dependencies down the stack I switched it to a JOIN which allows the OR condition. More verification of results will be done.

Related

Nested Table Joins

I have C table as Main Table, which is joining left join with E table on col3 and which is joining left join with F table on col4.
(
FROM A
LEFT OUTER JOIN B ON A.col1 = B.col1
LEFT OUTER JOIN C ON A.col2 = C.col2
LEFT OUTER JOIN E ON A.col3 = E.col3
LEFT OUTER JOIN F ON A.col4 = F.col4
)temptab1
Which needs to left join with
(
FROM C ON
LEFT OUTER JOIN E ON C.col3 = E.col3
LEFT OUTER JOIN F ON C.col4 = F.col4
)temptab2
Now, should i join temptab1 to temptab2 on (C.Col3 = temptab2.Col3 OR C.Col4 = temptab2.Col4) ? OR
should i join temptab1 to temptab2 on (C.Col3 = temptab2.Col3 AND C.Col4 = temptab2.Col4) ?
IF i have to use OR clause, it is hindering performance of the query a lot...
I tried using union clause instead of OR clause. Still, query performance is not improving...
Please suggest better query.
The temptab1 is all rows of A. The temptab2 is all rows of C. And the temptab1 is LEFT JOIN with temptab2, which results in all rows of A.
You may use CASE statements to identify the matching values across A, B, C, D, E, F and remove the Join with temptab2.
Apologies, could not comment...

Oracle inner and outer join valid combinations

Is it valid to combine Oracle inner and outer joins in the same query a la:
select b.col1, c.col2, sum(d.col1), sum(e.col1) from
a
inner join b on a.xxx = b.xxx
inner join c on a.yyy = c.yyy
left join d on b.aaa = d.aaa and c.bbb = d.bbb
left join e on b.aaa = e.bbb and c.aaa = e.bbb
group by b.col1, c.col2
Yes, you can combine inner, left and right joins the way you deem fit in the query. Just make sure that you understand the implications of inner, left and outer joins. Couple of blogs describe joins nicely: http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/ and http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
The outer join nulls are ignored in your sum(d.col1) and sum(e.col1) values.
Why SUM(null) is not 0 in Oracle?
If alternate default values are needed for your null outer join results, consider NVL and similar.
Sum columns with null values in oracle
Please try this, All non aggregated columns should be in group by clause.
select b.col1, c.col2, sum(d.col1), sum(e.col1) from
a
inner join b on a.xxx = b.xxx
inner join c on a.yyy = c.yyy
left join d on b.aaa = d.aaa and c.bbb = d.bbb
left join e on b.aaa = e.bbb and c.aaa = e.bbb
group by b.col1, c.col2

How to write a transitive sql join in DB2?

I want something like the following.
SELECT fewCols, aColFromNewTbl FROM TABLE_A AS A
LEFT OUTER JOIN TABLE_B AS B ON A.ID = B.ID
LEFT OUTER JOIN TABLE_C AS C ON A.ID = C.ID
INNER JOIN A_NEW_TABLE AS NEWTBL ON NEWTBL.ID = B.ID;
Somehow I'm not able to achieve this functionality. Actually above query is suppose to join A with NEWTBL, but I'm joining it with B, which is already joined with A. For my results I want them to come exclusively from the join of NEWTBL and B. I don't know how I can get desired results?
Probably you need this:
SELECT fewCols, aColFromNewTbl
FROM TABLE_A AS A
LEFT OUTER JOIN TABLE_B AS B
INNER JOIN A_NEW_TABLE AS NEWTBL
ON NEWTBL.ID = B.ID
ON A.ID = B.ID
LEFT OUTER JOIN TABLE_C AS C
ON A.ID = C.ID;

Best way to join parent and child tables

I have Parent table A.
A has few child tables such as B,C,D,E,F,G
The child tables are not linked to each other. They are only linked to A.
A has a key Id which is used as foreign key in all the child tables.
What should be the best way to join these tables so I can create a single view on this?
Since a parent may have a child row in some of those tables you must use LEFT OUTER JOIN.
LEFT OUTER JOIN joins two tables returning all the rows of the LEFT table, in this case A and all the matches from the other tables. When there is no match it will return NULL in the corresponding columns of the tables that there was no match.
SELECT *
FROM A
LEFT OUTER JOIN B
ON A.Id = B.ParentID
LEFT OUTER JOIN C
ON A.Id = C.ParentID
LEFT OUTER JOIN P
ON C.Id = P.ParentID
LEFT OUTER JOIN Q
ON C.Id = Q.ParentID
LEFT OUTER JOIN D
ON A.Id = D.ParentID
LEFT OUTER JOIN E
ON A.Id = E.ParentID
LEFT OUTER JOIN F
ON A.Id = F.ParentID
LEFT OUTER JOIN X
ON F.Id = X.ParentID
LEFT OUTER JOIN Y
ON F.Id = Y.ParentID
LEFT OUTER JOIN G
ON A.Id = G.ParentID
EDIT
I have added a way to add subchilds. I have intented them more just to make them obvious in a visual representation. But beware...if this lead to subchildren have other subchildren etc maybe your structure is not optimal.
select <wanted columns>
from a
left join b
on a.id = b.a_id
left join c
on a.id = c.a_id
left join d
on a.id = d.a_id

Cascading left outer joins

What is the correct syntax to perform an outer join with the following requirements:
A left outer join B on A.c1 = B.c1
B left outer join C on B.c2 = C.c2
A left outer join D on A.c1 = D.c1
So A, B, and C cascade and A and D cascade.
I know how to write the A->B->C but I don't know how to add D. I need scope or parenthesis or something.
this should work as you want:
SELECT
*
FROM A
left outer join B on A.c1 = B.c1
left outer join C on B.c2 = C.c2
left outer join D on A.c1 = D.c1
the DB engine looks at what your are joining to, not the order of the joins. D joins to A, and has nothing to do with B or C
The order in which you join doesn't matter, the database will build a result set of every combination of rows in all tables, limited by the on clause. For example, because 1=1 is always true, this would give you 1000 rows:
select *
from ten_row_table A
left join ten_row_table B on 1=1
left join ten_row_table C on 1=1
But this would give you 10 rows:
select *
from ten_row_table A
left join ten_row_table B on A.id = B.id
left join ten_row_table C on A.id = C.id
You can make complicated queries slightly more readable by indentation. We indent second and further dependencies by four spaces, like:
from A
left outer join B on A.c1 = B.c1
left outer join C on B.c2 = C.c2
left outer join D on C.c3 = D.c3
left outer join E on B.c2 = E.c2
left outer join F on A.c1 = F.c1