Solved

SQL - Left joins and where clauses

Posted on 2009-05-06
9
175 Views
Last Modified: 2012-05-06
Hi there,

A general question really .. if I have some left joins in my sql, do I need to put all the conditions in the main where clause in each left join? Code sample attached,

Thankyou,

Roger
0
Comment
Question by:Rogero
  • 6
  • 3
9 Comments
 

Author Comment

by:Rogero
ID: 24312270
File attached
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 24312276
nothing attached so far, but anyhow:


SELECT * FROM tableA a LEFT JOIN TableB b ON a.key = b.key WHERE b.somefield = somevalue
 

is no longer a LEFT JOIN, but a INNER JOIN, aka, will work as if you wrote:

SELECT * FROM tableA a INNER JOIN TableB b ON a.key = b.key WHERE b.somefield = somevalue
 

correct way:

SELECT * FROM tableA a LEFT JOIN TableB b ON a.key = b.key AND b.somefield = somevalue
 

UNLESS you write this:

SELECT * FROM tableA a LEFT JOIN TableB b ON a.key = b.key WHERE b.key IS NULL

to find only those record in tableA that are not in table B

Open in new window

0
 

Author Comment

by:Rogero
ID: 24312305
Here is my code ..

SELECT             
      d.cname,
      m.subcode,
      count(distinct m.invoiceno) as InvTotalCount,
      count(distinct m1.Invoiceno) as InvCompletecount,
      count(distinct m2.Invoiceno) as InvPassCount,
      count(distinct m3.Invoiceno) as InvFailCount,
      sum(case when m.qastatus is not null then 1 else 0 end) as mainmeasurecount,
      sum(case when m.qastatus in ('o', 'p') then 1 else 0 end) as mainmeasurepasscount,
      sum(case when m.qastatus = 'f' then 1 else 0 end) as mainmeasurefailcount
FROM             
      dbo.FCMEASURES m
      JOIN dbo.FCJOB j  on j.invoiceno = m.invoiceno
      JOIN dbo.KIMSGROUPS k  on k.code = m.servicecode
      JOIN dbo.FCDIST d  on d.code = m.subhocode
      LEFT JOIN dbo.fcmeasures m1  on j.invoiceno = m1.invoiceno       and m1.servicegrp = 19
                                                      and m1.status = 'A'
                                                      and m1.completedate is not null
      LEFT JOIN dbo.fcmeasures m2  on j.invoiceno = m2.invoiceno       and m2.servicegrp = 19
                                                      and m2.status = 'A'
                                                      and m2.completedate is not null
                                                      and m2.qastatus in ('p', 'o')
      LEFT JOIN dbo.fcmeasures m3  on j.invoiceno = m3.invoiceno       and m3.servicegrp = 19
                                                      and m3.status = 'A'
                                                      and m3.completedate is not null
                                                      and m3.qastatus not in ('p', 'o')
WHERE             
      k.main = 'Y'
      and m.completedate is not null
      and m.canceldate is null

GROUP BY       
      m.subhocode, d.cname
order by 1

0
 

Author Comment

by:Rogero
ID: 24312339
do i need to put the k.main = 'Y' into each left join? I would need to add more tables to do this in each left join .. or does the k.main = 'Y' in the main where clause handle it all?
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 24312395
>do i need to put the k.main = 'Y' into each left join?
no, because k table is not left joined, but inner joined

you could nevertheless move that condition to the JOIN condition
SELECT             

      d.cname,

      m.subcode,

      count(distinct m.invoiceno) as InvTotalCount,

      count(distinct m1.Invoiceno) as InvCompletecount,

      count(distinct m2.Invoiceno) as InvPassCount,

      count(distinct m3.Invoiceno) as InvFailCount,

      sum(case when m.qastatus is not null then 1 else 0 end) as mainmeasurecount,

      sum(case when m.qastatus in ('o', 'p') then 1 else 0 end) as mainmeasurepasscount,

      sum(case when m.qastatus = 'f' then 1 else 0 end) as mainmeasurefailcount

FROM             

      dbo.FCMEASURES m 

      JOIN dbo.FCJOB j  on j.invoiceno = m.invoiceno

      JOIN dbo.KIMSGROUPS k  on k.code = m.servicecode and k.main = 'Y' 

      JOIN dbo.FCDIST d  on d.code = m.subhocode

      LEFT JOIN dbo.fcmeasures m1  on j.invoiceno = m1.invoiceno       and m1.servicegrp = 19 

                                                      and m1.status = 'A' 

                                                      and m1.completedate is not null 

      LEFT JOIN dbo.fcmeasures m2  on j.invoiceno = m2.invoiceno       and m2.servicegrp = 19 

                                                      and m2.status = 'A' 

                                                      and m2.completedate is not null 

                                                      and m2.qastatus in ('p', 'o')

      LEFT JOIN dbo.fcmeasures m3  on j.invoiceno = m3.invoiceno       and m3.servicegrp = 19 

                                                      and m3.status = 'A' 

                                                      and m3.completedate is not null

                                                      and m3.qastatus not in ('p', 'o')

WHERE m.completedate is not null 

  AND m.canceldate is null
 

GROUP BY       

      m.subhocode, d.cname

order by 1

Open in new window

0
 

Author Comment

by:Rogero
ID: 24312414
Thanks Angellll, that helps.

Can you see why I have the left joins there (so I can get the m1, m2 qnd m3 counts correctly) .. is there a better way to write this qry?
0
 

Author Comment

by:Rogero
ID: 24312535
The m1 count should equal m2+m3 counts but unfortunately the code is not returning this result
0
 
LVL 142

Accepted Solution

by:
Guy Hengel [angelIII / a3] earned 500 total points
ID: 24312570
when you join to several tables, and need to count both of them apart, you have to FIRST group by in a subquery, and then join.

chinese?

here we go:
SELECT             

      d.cname,

      m.subcode,

      max(m1.InvCompletecount) InvCompletecount, 

      ...
 

      sum(case when m.qastatus is not null then 1 else 0 end) as mainmeasurecount,

      sum(case when m.qastatus in ('o', 'p') then 1 else 0 end) as mainmeasurepasscount,

      sum(case when m.qastatus = 'f' then 1 else 0 end) as mainmeasurefailcount

FROM             

      dbo.FCMEASURES m 

      JOIN dbo.FCJOB j  on j.invoiceno = m.invoiceno

      JOIN dbo.KIMSGROUPS k  on k.code = m.servicecode and k.main = 'Y' 

      JOIN dbo.FCDIST d  on d.code = m.subhocode

      LEFT JOIN ( SELECT invoiceno   

                       , count(*) InvCompletecount

                   FROM dbo.fcmeasures m1  

                  WHERE m1.servicegrp = 19 

                    and m1.status = 'A' 

                    and m1.completedate is not null 

                 ) m1 

           ON j.invoiceno = m1.invoiceno       

       .... 

WHERE m.completedate is not null 

  AND m.canceldate is null

 

GROUP BY       

      m.subhocode, d.cname

order by 1

Open in new window

0
 

Author Closing Comment

by:Rogero
ID: 31578361
Thanks this has helped
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Access Query 4 46
mySql Syntax 7 44
MS Sql query to list a table and join another table though all rows are not there 13 44
Query Records that don't match 8 32
In database programming, custom sort order seems to be necessary quite often, at least in my experience and time here at EE. Within the realm of custom sorting is the sorting of numbers and text independently (i.e., treating the numbers as number…
This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now