Home > Mobile >  SQL Server remove EXCEPT and just have in WHERE/AND statements
SQL Server remove EXCEPT and just have in WHERE/AND statements

Time:10-07

Hi I have the following SQL that I want to refactor and remove the EXCEPT

The SQL chunk is as follows:

UPDATE pv SET pv.EndDate = @newEndDate, pv.AuditUser = @auditUser
FROM PriceValues pv
INNER JOIN Prices p ON pv.PriceId = p.Id
INNER JOIN (
            SELECT Id FROM #RowsIWant 
            EXCEPT
            SELECT p.Id
            FROM PriceValues pv
            INNER JOIN #RowsIWant AS p ON pv.PriceId = p.Id
            WHERE pv.StartDate > @currentExpiryDate
            AND @newEndDate >= pv.StartDate
) up ON p.Id = up.Id
WHERE pv.EndDate = @currentExpiryDate
AND p.Active = 1

How can I remove the EXCEPT and just add extra AND's to the bottom

Originally I though I could just reverse the greater than symbols like this example, but I'm not convinced this is right and my mind cant seem to figure it out!

UPDATE pv SET pv.EndDate = @newEndDate, pv.AuditUser = @auditUser
FROM #RowsIWant AS P
INNER JOIN PriceValues AS PV ON pv.PriceId = P.PriceId
WHERE pv.EndDate = @currentExpiryDate
AND pv.StartDate < @currentExpiryDate
AND @newEndDate <= pv.StartDate
AND p.Active = 1

CodePudding user response:

This query:

SELECT Id FROM #RowsIWant 
EXCEPT
SELECT p.Id
FROM PriceValues pv
INNER JOIN #RowsIWant AS p ON pv.PriceId = p.Id
WHERE pv.StartDate > @currentExpiryDate
AND @newEndDate >= pv.StartDate

Is logically equivalent to:

SELECT p.Id
FROM #RowsIWant  pv
LEFT JOIN PriceValues AS p ON pv.PriceId = p.Id
WHERE pv.Id IS NULL 
    AND pv.StartDate > @currentExpiryDate
    AND @newEndDate >= pv.StartDate

The basic concept is that you can use left join, to find where there isn't a match.

CodePudding user response:

You can change the first part to a normal join, and the second half to NOT EXISTS

UPDATE pv
SET pv.EndDate = @newEndDate,
    pv.AuditUser = @auditUser
FROM PriceValues pv
INNER JOIN Prices p ON pv.PriceId = p.Id
INNER JOIN #RowsIWant riw ON p.Id = riw.Id
WHERE pv.EndDate = @currentExpiryDate
  AND p.Active = 1
  AND NOT EXISTS (SELECT 1
    FROM PriceValues pv2
    WHERE pv2.PriceId = p.Id
      AND pv2.StartDate > @currentExpiryDate
      AND @newEndDate >= pv2.StartDate
  )

You could also use LEFT JOIN / IS NULL like the other answer, but that is generally not as efficient.

Don't fall into the trap of using NOT IN, because it doesn't deal well with nulls.

  • Related