grupos ConCat en SQL Server [Duplicar]
-
06-09-2019 - |
Pregunta
Esta pregunta ya tiene una respuesta aquí:
Si tengo una tabla como la siguiente:
+------------+
| Id | Value |
+------------+
| 1 | 'A' |
|------------|
| 1 | 'B' |
|------------|
| 2 | 'C' |
+------------+
¿Cómo puedo obtener un conjunto de resultados como esto:
+------------+
| Id | Value |
+------------+
| 1 | 'AB' |
|------------|
| 2 | 'C' |
+------------+
Sé que esto es muy fácil de hacer en MySQL utilizando GROUP_CONCAT, pero tengo que ser capaz de hacerlo en MSSQL 2005
Gracias
(Duplicado del Cómo utilizar GROUP BY a concatenar cadenas en SQL Server? )
Solución
Para obtener una solución limpia y eficiente puede crear un usuario función de agregado definida , hay incluso un ejemplo que hace precisamente lo que necesitar.
A continuación, puede utilizarlo como cualquier otra función de agregado (con un plan de consulta estándar):
Otros consejos
Esto va a hacer:
SELECT mt.ID,
SUBSTRING((SELECT mt2.Value
FROM MyTable AS mt2
WHERE mt2.ID = mt.ID
ORDER BY mt2.VALUE
FOR XML PATH('')), 3, 2000) AS JoinedValue
FROM MyTable AS mt
A menudo aquí pedido.
La forma más eficiente está utilizando el truco CAMINO PARA XML.
Esto acaba de llegar a mí como una posible solución. No tengo ni idea en cuanto a rendimiento, pero pensé que sería una interesante forma de resolver el problema. He probado que funciona en una situación simple (que no código para dar cuenta de los nulos). No dude en darle una prueba para ver si funciona bien para usted.
La tabla que he utilizado incluyó un id (my_id). Que realmente podría ser cualquier columna que es único en el grupo (grp_id), por lo que podría ser una columna de fecha o lo que sea.
;WITH CTE AS (
SELECT
T1.my_id,
T1.grp_id,
CAST(T1.my_str AS VARCHAR) AS my_str
FROM
dbo.Test_Group_Concat T1
WHERE NOT EXISTS (SELECT * FROM dbo.Test_Group_Concat T2 WHERE T2.grp_id = T1.grp_id AND T2.my_id < T1.my_id)
UNION ALL
SELECT
T3.my_id,
T3.grp_id,
CAST(CTE.my_str + T3.my_str AS VARCHAR)
FROM
CTE
INNER JOIN dbo.Test_Group_Concat T3 ON
T3.grp_id = CTE.grp_id AND
T3.my_id > CTE.my_id
WHERE
NOT EXISTS (SELECT * FROM dbo.Test_Group_Concat T4 WHERE
T4.grp_id = CTE.grp_id AND
T4.my_id > CTE.my_id AND
T4.my_id < T3.my_id)
)
SELECT
CTE.grp_id,
CTE.my_str
FROM
CTE
INNER JOIN (SELECT grp_id, MAX(my_id) AS my_id FROM CTE GROUP BY grp_id) SQ ON
SQ.grp_id = CTE.grp_id AND
SQ.my_id = CTE.my_id
ORDER BY
CTE.grp_id