У меня есть некоторые customer_comments
разбиты на несколько строк из-за дизайна базы данных, и для отчета мне нужно объединить comments
из каждого уникального id
в одну строку. Ранее я пытался что-то работать с этим разделенным списком из предложения SELECT и трюка COALESCE, но я не могу вспомнить это и не должен был его сохранить. Я не могу заставить его работать в этом случае, кажется, работает только в одной строке.
Данные выглядят так:
id row_num customer_code comments
-----------------------------------
1 1 Dilbert Hard
1 2 Dilbert Worker
2 1 Wally Lazy
Мои результаты должны выглядеть так:
id customer_code comments
------------------------------
1 Dilbert Hard Worker
2 Wally Lazy
Таким образом, для каждого row_num
есть только один ряд результатов; комментарии должны быть объединены в порядке row_num
. Приведенный выше SELECT
трюк работает, чтобы получить все значения для определенного запроса в виде одной строки, но я не могу понять, как заставить его работать как часть SELECT
оператора, который выплевывает все эти строки.
Мой запрос должен пройти всю таблицу самостоятельно и вывести эти строки. Я не объединяю их в несколько столбцов, по одному для каждой строки, поэтому PIVOT
не представляется возможным.
источник
order by
в подзапросе. Это построение XML с использованием ,for xml
и это способ построения XML с использованием TSQL. Порядок элементов в файлах XML является важным вопросом и на него можно положиться. Так что если этот метод не гарантирует порядок, то поддержка XML в TSQL серьезно нарушена.row_num desc
должен подчиняться,order by
как предложил Микаэль). Я собираюсь удалить комментарии, предлагающие обратное, теперь, когда запрос содержит право,order by
и надеюсь, что @JonSeigel подумает о том же.Если вам разрешено использовать CLR в вашей среде, это индивидуальный подход для пользовательского агрегата.
В частности, это, вероятно, тот путь, если исходные данные нетривиально велики, и / или вам нужно много чего делать в своем приложении. Я сильно подозреваю, что план запроса для решения Аарона не будет хорошо масштабироваться по мере увеличения размера ввода. (Я попытался добавить индекс во временную таблицу, но это не помогло.)
Это решение, как и многие другие, является компромиссом:
РЕДАКТИРОВАТЬ: Ну, я пошел, чтобы попытаться увидеть, было ли это на самом деле лучше, и оказалось, что требование, чтобы комментарии были в определенном порядке, в настоящее время невозможно удовлетворить с помощью функции агрегирования. :(
См. SqlUserDefinedAggregateAttribute.IsInvariantToOrder . По сути, вам нужно,
OVER(PARTITION BY customer_code ORDER BY row_num)
ноORDER BY
не поддерживается вOVER
предложении при агрегировании. Я предполагаю, что добавление этой функции в SQL Server открывает червя, потому что то, что нужно изменить в плане выполнения, тривиально. Вышеупомянутая ссылка говорит, что это зарезервировано для будущего использования, так что это может быть реализовано в будущем (хотя в 2005 году вам, вероятно, не повезло).Это может еще быть достигнуто путем упаковки и разбора
row_num
значения в агрегированной строку, а затем делает вид внутри объекта CLR ... который кажется довольно хаком.В любом случае, ниже приведен код, который я использовал на тот случай, если кто-то сочтет это полезным, даже с ограничениями. Я оставлю хакерскую часть как упражнение для читателя. Обратите внимание, что я использовал AdventureWorks (2005) для тестовых данных.
Агрегатная сборка:
T-SQL для тестирования (
CREATE ASSEMBLY
иsp_configure
для включения CLR опущено):источник
Вот решение на основе курсора, которое гарантирует порядок комментариев по
row_num
. (См. Мой другой ответ о том, как[dbo].[Comments]
таблица была заполнена.)источник
источник