tags:

views:

96

answers:

3

i have 2 tables Group and People

People has GroupId that is linked to Group.GroupId (primary key)

how can I select groups that don't have any people? in t-sql and in linq

thank you

+1  A: 

Update

I've run four different ways to do this through SQL Server 2005 and included the execution plan.

-- 269 reads, 16 CPU
SELECT *
FROM Groups
WHERE NOT EXISTS (
    SELECT *
    FROM People
    WHERE People.GroupId = Groups.GroupId
);

-- 249 reads, 15 CPU
SELECT *
FROM Groups
WHERE (
    SELECT COUNT(*)
    FROM People
    WHERE People.GroupId = Groups.GroupId
) = 0

-- 249 reads, 14 CPU
SELECT *
FROM Groups
WHERE GroupId NOT IN (
    SELECT DISTINCT GroupId
    FROM Users
)

-- 10 reads, 12 CPU
SELECT *
FROM Groups
    LEFT JOIN Users ON Users.GroupId = Groups.GroupId
WHERE Users.GroupId IS NULL

So the last one, while arguably the least readable of the four, performs the best.

That comes as something as a surprise to me, and honestly I still prefer the WHERE NOT EXISTS syntax because I think it's more explicit - it reads exactly like what you're trying to do.

Matt Hamilton
wow this is great. thank youhow did you get the cpu stats?
SQL Server's Profiler. It tells you how many reads and CPU time each query took (I ran them one by one).
Matt Hamilton
+3  A: 

My preferred method is a left-anti-semi join:

SELECT    g.*
FROM      Groups g
LEFT JOIN People p ON g.GroupID = p.GroupID
WHERE     p.GroupID IS NULL

I find it most intitive, flexible, and performant.

I wrote an entire article on various query strategies to search for the absence of data - have a look here if you're interested.

Aaron Alton
I dunno if I find it more intuitive than WHERE NOT EXISTS, but +1 nonetheless.
Matt Hamilton
+1, outer join and checking for `IS NULL` is definitely a well-performing approach in mysql (not sure how it compares performance-wise to `WHERE NOT EXITS` in various SQL Server editions, though).
Alex Martelli
+1  A: 

I think the simplest solution is:

SELECT * 
FROM GROUPS
WHERE GroupId NOT IN (SELECT DISTINCT GroupId FROM People)
Roee Adler