Я играл с этим некоторое время, и, хотя есть некоторые подходы «грубой силы», которые технически работают, я чувствую, что мне не хватает что-то более элегантное (и эффективное).SQL Server: как эффективно вернуть объединенный результирующий набор из двух немного разных запросов
У меня есть таблица, содержащая историю событий. Для каждого события есть «источник» и «пункт назначения» (это то, что я фильтрую). Мне нужно вернуться в верхние n строк, упорядоченных по дате (сначала последней), сначала для определенного адресата из определенного источника, а затем для одного и того же адресата для любого источника, отличного от того, который использовался в первом запросе. Например, если первый запрос (соответствующий как получателю, так и источнику) возвращает n строк, мне не нужны строки из второго запроса (соответствующие одному и тому же адресу и соответствующему любому другим источникам), но если первый запрос возвращает меньше чем n строк, мне нужно, чтобы остальное было заполнено вторым запросом (предполагая, что есть такие строки).
Использование UNION ALL не работает, поскольку отдельные запросы не могут быть отсортированы отдельно, поэтому я получаю набор результатов, содержащий верхний n «любого» источника для данного адресата (если бы я мог включить ORDER BY в каждом отдельном запросе, это, вероятно, будет разумное решение):
SELECT TOP (100) * FROM
(
SELECT TOP (100) Destin, Source, OtherData, Timestamp
FROM History
WHERE Destin = @Destin
AND Source = @source
UNION ALL
SELECT TOP (100) Destin, Source, OtherData, Timestamp
FROM History
WHERE Destin = @Destin
AND Source <> @source
ORDER BY Timestamp DESC
) AS SubQuery
ORDER BY TimeStamp DESC
Я попытался КТР, как хорошо, но ничего лучшего на этом фронте не найдено. Любые идеи об альтернативных подходах?
PS - TOP (100) в подзапросах - попытка повысить производительность, но я не могу сказать, будет ли SQL Server автоматически останавливать запуск первого (или второго) подзапроса, когда он удовлетворяет TOP (100) во внешнем запросе (что было бы идеальным).
Ваша сортировка по метке. Означает ли это, что результаты приходят сначала с первой половины профсоюза? – shawnt00
@ shawnt00: Да; показанный запрос не совсем работает, поскольку ограничение UNION ALL не позволяет сортировать отдельные запросы; цель состоит в том, чтобы получить первые 100 строк, самые последние до самых старых, «предпочитая» те, которые соответствуют как месту назначения, так и источнику, но затем «завершают» набор результатов теми, которые соответствуют только месту назначения. – eric
Ну, проблема сортировки обрабатывается добавлением дополнительного столбца к результатам, например '1 as src' и' 2 as src'. Затем вы можете сортировать по 'src'. Это не относится к соображениям производительности, хотя это может быть связано с запуском запросов отдельно внутри proc и, при необходимости, объединением результатов. – shawnt00