Solved

SQL - Left joins and where clauses

Posted on 2009-05-06
9
179 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
9 Comments
 

Author Comment

by:Rogero
ID: 24312270
File attached
0
 
LVL 143

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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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
 
LVL 143

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 143

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

Turn Insights Into Action

You’ve already invested in ITSM tools, chat applications, automation utilities, and more. Fortify these solutions with intelligent communications so you can drive business processes forward.

With xMatters, you'll never miss a beat.

Question has a verified solution.

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

I'm trying, I really am. But I've seen so many wrong approaches involving date(time) boundaries I despair about my inability to explain it. I've seen quite a few recently that define a non-leap year as 364 days, or 366 days and the list goes on. …
If you have heard of RFC822 date formats, they can be quite a challenge in SQL Server. RFC822 is an Internet standard format for email message headers, including all dates within those headers. The RFC822 protocols are available in detail at:   ht…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…

717 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