SQL Server 2000: Idéias para executar a subconsulta de agregação de concatenação
tenho uma consulta que retorna as linhas que eu quero, por exemplo
QuestionID QuestionTitle UpVotes DownVotes
========== ============= ======= =========
2142075 Win32: Cre... 0 0
2232727 Win32: How... 2 0
1870139 Wondows Ae... 12 0
Agora eu quero ter umcoluna retornado, que contém uma lista separada por vírgula de "Autores"(por exemplo, pôster e editores originais). Por exemplo:
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
O SQL Server 2000 não possui umCONCAT(AuthorName, ', ')
operação de agregação, estou fingindo - realizando sub-seleções simples para oTOP 1
autor e a contagem de autores.
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
Se houver mais de um autor, mostrarei ao usuário uma elipse ("..."), para indicar que há mais de um. por exemplo. o usuário veria:
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, …
E isso funciona bem o suficiente, já que normalmente umPergunta, questão não é editado - o que significa que estou apoiando perfeitamente o caso de 99% e o caso de 1% apenas metade-assed também.
Como uma solução mais complicada e propensa a erros, eu estava pensando em iterar a lista exibida e girar um thread de trabalho do pool de threads para cada "Pergunta, questão"na lista, execute uma consulta no banco de dados para obter a lista de autores e, em seguida, agregue a lista na memória. Isso significa que a lista é preenchida primeiro no aplicativo (nativo). Em seguida, emito alguns milhares de consultas individuais posteriormente.
Mas isso seria terrivelmente, terrivelmente, terrivelmente lento. Sem mencionar um enigma cheio de erros, pois será um trabalho de thread.
Adam Mechanicdiz claramente:
Não concatene linhas em seqüências delimitadas no SQL Server. Faça do lado do cliente.
Diga-me como, e eu farei.
Alguém pode pensar em uma solução melhor, que seja tão rápida (digamos ... dentro de uma ordem de grandeza) quanto a minha solução original "TOP 1 mais elipses"?
Por exemplo, existe uma maneira de retornar um conjunto de resultados, onde a linha de alcance tem um conjunto de resultados associado? Assim, para cada linha "principal", eu poderia obter um conjunto de resultados "detalhados" que contém a lista.
Cade Link paraA solução de Adam Machanic eu gosto do melhor Uma função definida pelo usuário, que parece operar via mágica:
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
Com um uso T-SQL de:
SELECT QuestionID, QuestionTitle, UpVotes, DownVotes, dbo.ConcatAuthors(AuthorID)
FROM Questions