SQL Server na prática

Resultados confiáveis de STRING_AGG no SQL Server

Defina ordem, duplicatas, valores ausentes e limites de tamanho das listas e escolha JSON quando for necessário preservar uma estrutura exata.

Uma lista separada por vírgulas parece apenas apresentação, mas depende de decisões sobre os dados. Quais linhas formam cada grupo? Duplicatas são relevantes? Um valor ausente precisa de marcador? Qual ordem deve ser exibida? STRING_AGG simplifica a concatenação sem decidir essas regras.

Os exemplos utilizam SQL Server 2017 ou posterior. WITHIN GROUP para ordenação exige compatibilidade da base de pelo menos 110. Verifique versão e compatibilidade quando a mesma instrução se comporta diferentemente entre ambientes.

Definir ordem e valores ausentes

Os dados contêm propositalmente uma etiqueta repetida e NULL.

DECLARE @Tags table (DocumentId int, TagId int, Tag nvarchar(100));
INSERT @Tags VALUES
(1, 1, N'Tuning'), (1, 2, N'Backup'), (1, 3, N'Tuning'),
(1, 4, NULL), (2, 5, N'Security');

SELECT DocumentId,
       STRING_AGG(CONVERT(nvarchar(max), Tag), N', ')
       WITHIN GROUP (ORDER BY Tag, TagId) AS TagList
FROM @Tags
GROUP BY DocumentId;

O documento 1 produz Backup, Tuning, Tuning na ordenação alfabética ilustrada. NULL não contribui texto nem separador adicional. O documento 2 produz Security. STRING_AGG não elimina duplicatas. Um ORDER BY externo ordenaria os grupos retornados, não os elementos de cada lista.

WITHIN GROUP estabelece a ordem interna. TagId desempata etiquetas consideradas iguais. Se o negócio precisa da ordem de atribuição, use uma sequência efetiva. A collation influencia comparação, acentos e diferenças de caixa; teste os valores realmente armazenados.

NULL e texto vazio são diferentes. NULL é ignorado; texto vazio continua sendo um valor e pode gerar um separador inesperado. Defina onde normalizar entradas vazias ou contendo somente espaços. Não remova caracteres significativos de códigos apenas para melhorar a aparência.

Para representar ausências, substitua NULL antes de agregar. O marcador não deve parecer um valor real. Outra opção é saída estruturada com null verdadeiro. Exibir Desconhecido não transforma a informação ausente em um dado conhecido.

Eliminar duplicatas na relação correta

Se a lista precisa de etiquetas únicas, retire repetições no nível desejado antes da concatenação.

;WITH DistinctTags AS (
    SELECT DISTINCT DocumentId, Tag
    FROM @Tags
    WHERE Tag IS NOT NULL
)
SELECT DocumentId,
       STRING_AGG(CONVERT(nvarchar(max), Tag), N', ')
       WITHIN GROUP (ORDER BY Tag) AS TagList
FROM DistinctTags
GROUP BY DocumentId;

O documento 1 passa a retornar Backup, Tuning. DISTINCT considera DocumentId e Tag juntos, permitindo que a mesma etiqueta continue em outro documento. Eliminar duplicatas globalmente perderia o relacionamento que o relatório precisa preservar.

Revise as junções antes de acrescentar DISTINCT. Vários comentários e várias etiquetas por documento podem multiplicar as linhas intermediárias. A deduplicação final pode esconder esse efeito enquanto outras somas continuam incorretas. Agregue a relação de etiquetas separadamente e só depois una uma linha por documento ao relatório.

A igualdade textual também interfere. Em collation insensível a maiúsculas, grafias diferentes podem ser agrupadas. Se existe uma forma canônica de exibição, defina como escolhê-la. DISTINCT sozinho não estabelece preferência entre representações equivalentes.

Controlar tamanho e formato

Converta a expressão de entrada para nvarchar(max) antes de STRING_AGG quando resultados longos forem legítimos. O tipo de retorno depende da entrada. Converter o agregado pronto chega tarde para evitar o limite usado durante sua construção. Mantenha compatibilidade entre tipos de separador e conteúdo.

Um tipo amplo não torna boa uma resposta sem limites. Centenas de milhares de relações podem consumir memória e produzir um tráfego enorme. Defina limites práticos, forneça registros paginados ou crie uma exportação separada para grupos excepcionais.

Uma lista de vírgulas não preserva dados sem ambiguidade quando os valores contêm vírgulas, aspas ou quebras de linha. FOR JSON mantém estrutura e escape para uma API. A string também não deve substituir a relação normalizada quando etiquetas precisam continuar sendo filtradas, validadas ou alteradas individualmente.

Teste duplicatas, NULL, vazios, textos multilíngues, separadores no conteúdo e resultados longos. Se a saída parecer cortada, compare o tamanho real no banco com os limites de exibição do cliente. A agregação confiável mantém o significado dos registros até o consumidor final.

Referências técnicas: Microsoft Learn: STRING_AGG · Microsoft Learn: FOR JSON.

Pergunte sobre este artigo

Tem alguma dúvida sobre este tema?

Conte o que você está avaliando ou onde encontrou dificuldades. Responderemos com uma recomendação prática.

Inquiries are not enabled in this preview.

Fazer uma pergunta sobre este artigo