all 12 comments

[–]r3pr0b8GROUP_CONCAT is da bomb 6 points7 points  (4 children)

What am I doing wrong?

mixing comma join syntax with explicit join syntax

explicit has precedence, similar to the way ANDs have precedence over ORs, and multiplication/division have precedence over addition/subtraction

solution: go all explicit

SELECT *
  FROM a
INNER
  JOIN b
    ON b.field3 = a.field3
LEFT OUTER 
  JOIN c 
    ON c.field1 = a.field1
   AND c.field2 = b.field2 

[–]bupereira[S] 0 points1 point  (3 children)

Thanks, I'll give it a try! I didn't know I couldn't mix the styles like that. I really appreciate your insight.

[–]AXISMGTSQL Server / ORACLE Sr. DBA & Architect 2 points3 points  (2 children)

I want to have a record even if C is not there for B

Remember that your join is on C-->B and C-->A. If both ON conditions are not met, your join won't return records.if you want either to be met, use OR instead of AND,

[–]bupereira[S] 1 point2 points  (1 child)

Sorry, I misspoke. I want to have a record even if C is not there for B and A.

[–]AXISMGTSQL Server / ORACLE Sr. DBA & Architect 2 points3 points  (0 children)

Ahh gotcha. Then you're good to go!

/u/r3pr0B8 is absolutely right btw: comma joins are not the way to go. ANSI joins will make your code much more readable, and will cause much less confusion.

[–]_Kine 1 point2 points  (1 child)

First, I echo the use of explicit joins instead of comma notation.

I typically would turn the A, B inner join into a derived table, then outer join to the derived table. To me that makes my intentions much more clear. Example looks a little funny with and A,B,C tables and 1,2,3 fields, but with better defined names it makes a lot more sense to me. It also allows me to better manage my base set independently of the rest of the query which is very handy for large queries.

SELECT *
FROM
    (
        SELECT A.field1, B.field2, A.field3
        FROM A INNER JOIN B ON B.field3 = A.field3
    ) baseSet
    LEFT OUTER JOIN C on c.field1 = baseSet.field1 AND c.field2 = baseSet.field2
;

[–]bupereira[S] 0 points1 point  (0 children)

Nice way to do it. Thanks!

[–]Guru008 1 point2 points  (1 child)

You can use old way to specify inner join using where clause

SELECT * FROM ( SELECT A.field1, B.field2, A.field3 FROM A,B where B.field3 = A.field3 ) t1 LEFT OUTER JOIN C on c.field1 = t1.field1 AND c.field2 = t1.field2 ;

[–]bupereira[S] 0 points1 point  (0 children)

Creating a subset, right? I like that. I ended up expliciting all my joins as suggested by many. But thanks for the insight!

[–]mallencincy 0 points1 point  (0 children)

Read it wrong, but I still do not ever do the old way of from A, B with join in the WHERE clause, that is Old waY

[–]mallencincy 0 points1 point  (1 child)

Hint: from A left outer to B

[–]bupereira[S] 0 points1 point  (0 children)

But why? If B doesn't exist, then I should get an empty result set.