У меня есть запрос, который возвращает строки, которые я хочу, например,
QuestionID QuestionTitle UpVotes DownVotes
========== ============= ======= =========
2142075 Win32: Cre... 0 0
2232727 Win32: How... 2 0
1870139 Wondows Ae... 12 0
Теперь я хочу получить столбец , который содержит разделенный запятыми список " Авторы " (например, оригинальный постер и редакторы). e.g.:
QuestionID QuestionTitle UpVotes DownVotes Authors
========== ============= ======= ========= ==========
2142075 Win32: Cre... 0 0 Ian Boyd
2232727 Win32: How... 2 0 Ian Boyd, roygbiv
1870139 Wondows Ae... 12 0 Ian Boyd, Aaron Klotz, Jason Diller, danbystrom
Faking It
SQL Server 2000 не имеет операции агрегации CONCAT(AuthorName, ', ')
, я ее притворял - выполнял простые подвыборы для автора TOP 1
и количества авторов.
QuestionID QuestionTitle UpVotes DownVotes FirstAuthor AuthorCount
========== ============= ======= ========= =========== ===========
2142075 Win32: Cre... 0 0 Ian Boyd 1
2232727 Win32: How... 2 0 Ian Boyd 2
1870139 Wondows Ae... 12 0 Ian Boyd 3
Если существует более одного автора, тогда я показываю пользователю эллипсы ("..."), чтобы указать, что их больше одного. например пользователь увидит:
QuestionID QuestionTitle UpVotes DownVotes Authors
========== ============= ======= ========= ==========
2142075 Win32: Cre... 0 0 Ian Boyd
2232727 Win32: How... 2 0 Ian Boyd, …
1870139 Wondows Ae... 12 0 Ian Boyd, …
И это работает достаточно хорошо, так как обычно вопрос не редактируется - это означает, что я полностью поддерживаю дело с 99%, а дело с 1% только наполовину , оцененное а также.
Повторный запрос с резьбой
Как более сложное и подверженное ошибкам решение, я думал об итерации отображаемого списка и обкатке рабочего потока пула потоков для каждого " вопрос " в списке, выполнить запрос по базе данных, чтобы получить список авторов, затем агрегирование списка в памяти. Это будет означать, что список заполняется первым в (родном) приложении. Затем я выдаю несколько тысяч отдельных запросов.
Но это было бы ужасно, ужасно, ужасно, медленно. Не говоря уже об ошибках, поскольку это будет работа с потоками.
Да, да, да
Адам Механик довольно ясно говорит :
Не объединять строки в разделители
строки в SQL Server. Сделай это клиент
сторона.
Скажи мне, как, и я сделаю это.
/ крик
Может ли кто-нибудь придумать лучшее решение, такое же быстрое (скажем, в пределах порядка), чем мое оригинальное решение "ТОП 1 плюс эллипсы"?
Например, есть ли способ вернуть набор результатов, где в строке достижения есть связанный набор результатов? Таким образом, для каждой «основной» строки я мог бы получить «подробный» набор результатов, содержащий список.
Код для лучшего ответа
Ссылка Кейда на Решение Адама Маханича Мне нравится больше всего. Пользовательская функция, которая, кажется, работает через магию:
CREATE FUNCTION dbo.ConcatAuthors(@QuestionID int)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @Output VARCHAR(8000)
SET @Output = ''
SELECT @Output = CASE @Output
WHEN '' THEN AuthorName
ELSE @Output + ', ' + AuthorName
END
FROM (
SELECT QuestionID, AuthorName, QuestionDate AS AuthorDate FROM Questions
UNION
SELECT QuestionID, EditorName, EditDate FROM QuestionEdits
) dt
WHERE dt.QuestionID = @QuestionID
ORDER BY AuthorDate
RETURN @Output
END
При использовании T-SQL:
SELECT QuestionID, QuestionTitle, UpVotes, DownVotes, dbo.ConcatAuthors(AuthorID)
FROM Questions