2

I'm trying to do something like this...

SELECT lc.Location, count(h.empID) as 'Count', lu.LBL
FROM swam.lookup lu
    LEFT JOIN swam.empTable h
    ON CASE
        WHEN lu.sac is null 
            THEN lu.POS = h.POS
        ELSE (
            lu.POS = h.POS
            and
            lu.sac = h.sac)
    INNER JOIN swam.Locations lc
        ON h.LocationID = lc.LocationID
GROUP BY lc.Location, lu.LBL
ORDER BY lc.Location

So, if lu.sac is null, then only join the tables on one common column. If it's not null, then it has to use both POS and SAC to join.

Is this possible?

blacksaibot
  • 265
  • 2
  • 12

3 Answers3

4

Don't use case. Just use direct boolean logic:

FROM swam.lookup lu LEFT JOIN
     swam.empTable h
     ON lu.POS = h.POS AND
        (lu.sac is null OR lu.sac = h.sac) INNER JOIN
     swam.Locations fs
     ON h.LocationID = lc.LocationID

As a bonus, the database engine can also table advantage of an index on pos in either (or both) tables.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • Is there any performance degradation when we put OR condition in Join or Where Condition in SQL Server i.e. non-sargable query? Refer below link :- https://en.wikipedia.org/wiki/Sargable – RGS Oct 05 '16 at 05:17
  • 1
    @RGS . . . If the query would otherwise use indexes, then there is likely to be a performance degradation. – Gordon Linoff Oct 06 '16 at 03:24
1
    SELECT lc.Location, count(h.empID) as 'Count', lu.LBL
FROM swam.lookup lu
    LEFT JOIN swam.empTable h
    ON  (lu.sac is null  AND lu.POS = h.POS) OR  
                   not(lu.sac is null)  AND lu.POS = h.POS   and lu.sac = h.sac
    INNER JOIN swam.Locations fs
        ON h.LocationID = lc.LocationID
GROUP BY lc.Location, lu.LBL
ORDER BY lc.Location
Cato
  • 3,652
  • 9
  • 12
1
SELECT lc.Location, count(h.empID) as 'Count', lu.LBL
FROM swam.lookup lu
LEFT JOIN swam.empTable h
  ON lu.POS = h.POS
 AND isnull(lu.sac, h.sac) = h.sac    
INNER JOIN swam.Locations fs
   ON h.LocationID = lc.LocationID  // this looks wrong lc is not defined
GROUP BY lc.Location, lu.LBL
ORDER BY lc.Location

and I think that last join will turn the left join intro and inner join

paparazzo
  • 44,497
  • 23
  • 105
  • 176