2013-07-23 2 views
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 of Guid.Empty. Я пытаюсь выполнить некоторое обслуживание базы данных и удалять учетные записи, которые были созданы, но никогда не использовались.Выбрать только родителей с одним ребенком

У меня первая часть запроса работает очень хорошо, но я не уверен, как правильно применить фильтр «Имею только один ребенок».

+0

Может ли вы описать пользователь, Streams и плейлисты таблицу? –

+0

Пользователи имеют отношения от 1 до многих с потоками. Потоки имеют отношение от 1 до многих к плейлистам. Я добавлю скриншот из таблиц, если это поможет? –

+0

Является ли ваша проблема просто ключевым словом? То есть, в своем предложении, вы можете просто сравнить подзапрос с «1» вместо «COUNT (1)»? – Zec

ответ

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 
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 
) 
) 
+0

Это близко. Я думаю, это дает мне представление о том, как это сделать. Спасибо! –

+0

@seanmk +1 помог мне написать – xagyg

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 
) 
) 
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 
) 
0

Без подразделов querys, имеющие или группы:

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 
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; 

Я не уверен, какие версии будут работать лучше. Это просто альтернативный способ взглянуть на вашу проблему.

Смежные вопросы