只选择有一个孩子的父母

时间:2013-07-23 00:14:35

标签: sql sql-server

SELECT TOP 4000 Users.Id
  FROM Users
  JOIN Streams ON Users.Id = Streams.UserId
  JOIN Playlists ON Streams.Id = Playlists.StreamId
  WHERE Playlists.FirstItemId = '00000000-0000-0000-0000-000000000000'
  //  Doesn't work
  HAVING COUNT(1) = (
    SELECT COUNT(Playlists.Id)
    FROM Playlists WHERE Playlists.StreamId = Streams.Id
)

我正在尝试选择只有Streams with 1 Playlist且其1个播放列表的FirstItemId为Guid.Empty的所有用户。我正在尝试进行一些数据库维护并删除已创建但从未使用过的帐户。

我的查询的第一部分工作得很好,但我不确定如何正确应用我的'只有1个孩子'过滤器。

6 个答案:

答案 0 :(得分:3)

我认为您可以使用WHERE NOT EXISTS子句轻松完成此任务

SELECT TOP 4000 Users.Id
  FROM Users
  JOIN Streams ON Users.Id = Streams.UserId
  JOIN Playlists ON Streams.Id = Playlists.StreamId
  WHERE Playlists.FirstItemId = '00000000-0000-0000-0000-000000000000'
  AND NOT EXISTS (
    SELECT 1 FROM Playlists
    WHERE Playlists.StreamId <> Playlists.FirstItemId
  )
)

答案 1 :(得分:1)

@seanmk有个好主意......就像这样...

SELECT TOP 4000 Users.Id
  FROM Users
  JOIN Streams ON Users.Id = Streams.UserId
  JOIN Playlists p ON Streams.Id = p.StreamId
  WHERE p.FirstItemId = '00000000-0000-0000-0000-000000000000'
  AND NOT EXISTS (
    SELECT 1 FROM Playlists q
    WHERE q.Id = p.Id
      AND q.FirstItemId <> p.FirstItemId
  )
)

答案 2 :(得分:1)

以下查询应符合您的要求。

SELECT TOP 4000 Users.Id
FROM Users
JOIN Streams ON Users.Id = Streams.UserId
JOIN Playlists ON Streams.Id = Playlists.StreamId
WHERE Playlists.FirstItemId = '00000000-0000-0000-0000-000000000000'
AND Playlists.StreamId IN (
  SELECT Playlists.StreamId
  FROM Playlists
  GROUP BY Playlists.StreamId
  HAVING COUNT(*) = 1
)

答案 3 :(得分:1)

尝试以下查询,选择不活动的用户

SELECT TOP 4000 Users.Id
FROM Users
JOIN Streams ON Users.Id = Streams.UserId
JOIN Playlists ON Streams.Id = Playlists.StreamId
WHERE Playlists.FirstItemId = '00000000-0000-0000-0000-000000000000'
AND (SELECT COUNT(Playlists.Id) FROM Playlists WHERE Playlists.StreamId = Streams.Id) =1

答案 4 :(得分:0)

没有子查询,拥有或分组:

SELECT TOP 4000 Users.Id
FROM Users
INNER JOIN Streams ON Users.Id = Streams.UserId
INNER JOIN Playlists p1 ON Streams.Id = p1.StreamId AND p1.FirstItemId = '00000000-0000-0000-0000-000000000000'
LEFT JOIN Playlists p2 ON Streams.ID = p2.StreamID and p2.FirstItemID <> '00000000-0000-0000-0000-000000000000'
WHERE p2.StreamID IS NULL

答案 5 :(得分:0)

这是查看问题的另一种方式。它不使用exists,而是使用条件聚合:

select top 4000 Id
from (SELECT u.Id,
             min(FirstItemId) as MinFI,
             max(FirstItemId) as MaxFI,
             min(p.Id) as minpid,
             max(pid) as maxpid
      FROM Users u JOIN
           Streams s
           ON u.Id = s.UserId join
           Playlists p
           ON s.Id = p.StreamId
      group by u.id
     ) u
where MinFi = MaxFi and MinFi = '00000000-0000-0000-0000-000000000000' and
      minpid = maxpid;

我不确定哪个版本的性能会更好。这只是查看问题的另一种方式。