Coalesce e dinâmica no SQL
-
05-09-2019 - |
Pergunta
Estou tendo dificuldade para descobrir como a fundir-se ou pivô em um conjunto de registros SQL parecida com esta:
ID VALUE GROUP
3 John 18
4 Smith 18
5 Microsoft 18
3 Randy 21
4 Davis 21
5 IBM 21
etc
E eu quero formatado como este
NEWVALUE GROUP
Smith, John (Microsft) 18
Davis, Randy (IBM) 21
Obrigado por todas as sugestões e ajuda!
Solução
Isto é o que eu fiz, eu espero que ele se encaixa para você
DECLARE @t table (id int, value VARCHAR(20), grupo int)
INSERT @T VALUES (3, 'John', 18)
INSERT @T VALUES (4, 'Smith', 18)
INSERT @T VALUES (5, 'Microsoft', 18)
INSERT @T VALUES (3, 'Randy', 21)
INSERT @T VALUES (4, 'Davis', 21)
INSERT @T VALUES (5, 'IBM', 21)
SELECT grupo, (SELECT value FROM @t t2 WHERE t2.grupo = t.grupo AND id = 4) + ', ' +
(SELECT value FROM @t t2 WHERE t2.grupo = t.grupo AND id = 3) + ' (' +
(SELECT value FROM @t t2 WHERE t2.grupo = t.grupo AND id = 5) + ')'
FROM @t t
GROUP BY grupo
Outras dicas
SELECT LEFT(gvalue, LEN(gvalue) - 1) AS newvalue, _group
FROM (
SELECT DISTINCT _group
FROM mytable
) qo
CROSS APPLY
(
SELECT value + ', '
FROM mytable qi
WHERE qi._group = qo._group
FOR XML PATH ('')
) gr(qvalue)
Se você tem sempre um conjunto de três codificado ID
de para cada _group
, você pode apenas usar:
SELECT m3._group, m3.value + ', ' + m4.value + '(' + m5.value + ')' AS newvalue
FROM mytable m3
LEFT JOIN
mytable m4
ON m4._group = m3.group
LEFT JOIN
mytable m5
ON m5._group = m3.group
WHERE m3.id = 3
AND m4.id = 4
AND m5.id = 5
O que você precisa não é articulada consulta, mas uma simples escolha com o grupo por e uma função de concatenação agregado. Mas eu não me lembro a função exata no tsql.
Update: não há nenhuma função de agregação concatenação no tsql mas desde sql2005 você pode escrever sua própria extensão para implementar essa função. Há uma abundância de exemplos no google busca por:. Tsql 2005 concatenação exemplo agregado
Este é um pouco piegas, mas eu acho que deve funcionar razoavelmente bem para um pequeno conjunto de dados. Se você tem um monte de dados que você precisa para criar um cursor e um loop.
select max(case when ID = 4 then VALUE else null end) + ', ' +
max(case when ID = 4 then VALUE else null end) + '( ' +
max(case when ID = 5 then VALUE else null end) + ') as NEWVALUE,
[GROUP]
group by [GROUP]