Вот еще один вызов для вас, SQL-гуру ...
Я написал здесь еще один вопрос о сопоставлении двух наборов результатов ( Как сопоставить / сравнить значения в двух наборах результатов в SQL Server 2008? ). Этот вопрос является продолжением этого вопроса и ответа, но так как это другая тема, я создаю его как новый вопрос.
Quassnoi предлагает следующее решение для выбора всех пользователей, которые соответствуют навыкам, необходимым для данного проекта:
SELECT *
FROM Users u
WHERE NOT EXISTS
(
SELECT NULL
FROM ProjectSkill ps
WHERE ps.pk_project = @someid
AND NOT EXISTS
(
SELECT NULL
FROM UserSkills us
WHERE us.fk_user = u.id
AND us.fk_skill = ps.fk_skill
)
)
Это прекрасно работает. Но что, если я хочу создать один запрос, в котором перечислены все проекты определенного дня, включая их наиболее подходящего пользователя. Я представляю себе следующий формат:
projectid userid
---------- -----------
1 1234
2 5678
3 4321
4 8765
Важно, что пользователю предлагается только один раз в списке! ... потому что проекты находятся в один и тот же день, и пользователи не должны бронироваться дважды.
Теперь я могу представить себе некоторый SQL, например:
SELECT p.id 'projectid', ( SELECT TOP 1 u.id
FROM Users u
WHERE NOT EXISTS
(
SELECT NULL
FROM ProjectSkill ps
WHERE ps.pk_project = p.id
AND NOT EXISTS
(
SELECT NULL
FROM UserSkills us
WHERE us.fk_user = u.id
AND us.fk_skill = ps.fk_skill
)
)
ORDER BY rating DESC
) 'userid'
FROM Projects p
WHERE startdate > @beginningofday
AND startdate < @endofday
Но это (очевидно) радостно предлагает одного и того же пользователя снова и снова, если у него есть необходимые навыки для проектов.
Есть ли у кого-нибудь предложения о том, как отслеживать, какие строки в таблице Users уже совпадают ранее в запросе? Может быть, использование переменной? Или есть другой умный способ обойти это, что мне не хватает?
Запрос должен выполняться на SQL Server 2008.
Любая помощь будет принята с благодарностью! Спасибо.
С уважением
Alex