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'
  //  Doesn't work
  HAVING COUNT(1) = (
    SELECT COUNT(Playlists.Id)
    FROM Playlists WHERE Playlists.StreamId = Streams.Id
)

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

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

4

6 回答 6

2

我认为您可以使用 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
  )
)
于 2013-07-23T00:21:53.067 回答
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
  )
)
于 2013-07-23T00:27:28.253 回答
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
于 2013-07-23T02:15:04.953 回答
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
)
于 2013-07-23T00:29:45.787 回答
0

This is an alternative way of looking at the question. Instead of using exists, it uses aggregation for the conditions:

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;

I'm not sure which versions would perform better. This is just an alternative way of looking at your problem.

于 2013-07-23T00:56:44.783 回答
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
于 2013-07-23T00:36:25.223 回答