Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 182
  • Last Modified:

SQL - Left joins and where clauses

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
Rogero
Asked:
Rogero
  • 6
  • 3
1 Solution
 
RogeroAuthor Commented:
File attached
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
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
 
RogeroAuthor Commented:
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
RogeroAuthor Commented:
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
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
>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
 
RogeroAuthor Commented:
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
 
RogeroAuthor Commented:
The m1 count should equal m2+m3 counts but unfortunately the code is not returning this result
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
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
 
RogeroAuthor Commented:
Thanks this has helped
0

Featured Post

Independent Software Vendors: 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!

  • 6
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now