简体   繁体   中英

SQL Server NOT EXISTS efficiency

I have two tables Card and History with a one-to-many relationship: one card can have one or many histories. Card has a CardId column, and History has a CardId and a StatusId column.

I want a SQL script which selects the only cards which have no one history with StatusId=310.

This is what I've tried.

SELECT 
    C.CardId 
FROM 
    Card C
WHERE NOT EXISTS (SELECT * 
                  FROM History H
                  WHERE H.CardId = C.CardId AND H.StatusId = 310)

But I want to know if there is an efficient way.

Thanks in advance.

To answer your question about whether there is a more efficient way:

Short answer: No, not exists is most likely the most efficient method.

Long answer: Aaron Bertrand's article with benchmarks for many different methods of doing the same thing Should I use not in, outer apply, left outer join, except, or not exists? Spoiler: not exists wins.

I would stick with your original code using not exists, but Aaron's article has many examples you can adapt to your situation to confirm that nothing else is more efficient.

select c.CardId 
  from Card c
  where not exists(
    select 1
      from History h
      where h.CardId=c.CardId 
        and h.StatusId=310
             )

What you're after is called a "negative JOIN". Here's a version without the subquery:

SELECT c.CardId
FROM Card c
LEFT OUTER JOIN History h
  ON h.CardId = c.CardId
  AND h.StatusId = 310
WHERE h.CardId IS NULL;

Your NOT EXISTS method looks reasonable but there is another approach.

SELECT *
FROM   Card C
WHERE  EXISTS (SELECT 1
               FROM   history H
               WHERE  H.CardId = C.CardId
               HAVING Count(CASE WHEN H.StatusId = 310 THEN 1 END) = 0) 

Check the performance by running both the queries with your real time data

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM