Tengo algunos customer_comments
divididos en varias filas debido al diseño de la base de datos, y para un informe necesito combinar el comments
de cada único id
en una fila. Previamente intenté algo trabajando con esta lista delimitada de la cláusula SELECT y el truco COALESCE, pero no puedo recordarlo y no debo haberlo guardado. Parece que tampoco puedo hacer que funcione en este caso, solo parece funcionar en una sola fila.
Los datos se ven así:
id row_num customer_code comments
-----------------------------------
1 1 Dilbert Hard
1 2 Dilbert Worker
2 1 Wally Lazy
Mis resultados deben verse así:
id customer_code comments
------------------------------
1 Dilbert Hard Worker
2 Wally Lazy
Entonces, para cada row_num
uno solo hay una fila de resultados; los comentarios deben combinarse en el orden de row_num
. El SELECT
truco vinculado anterior funciona para obtener todos los valores para una consulta específica como una fila, pero no puedo entender cómo hacer que funcione como parte de una SELECT
declaración que escupe todas estas filas.
Mi consulta tiene que recorrer toda la tabla por sí sola y generar estas filas. No los estoy combinando en varias columnas, una para cada fila, por lo PIVOT
que no parece aplicable.
fuente
order by
en la subconsulta. Esto es construir XML usandofor xml
y esa es la manera de construir XML usando TSQL. El orden de los elementos en un archivo XML es un asunto importante y se puede confiar en él. Entonces, si esta técnica no garantiza el orden, entonces el soporte XML en TSQL está severamente roto.row_num desc
debe obedecer a loorder by
que sugirió Mikael). Voy a eliminar los comentarios que sugieran lo contrario ahora que la consulta contiene el derechoorder by
y espero que @JonSeigel considere hacer lo mismo.Si puede usar CLR en su entorno, este es un caso personalizado para un agregado definido por el usuario.
En particular, este es probablemente el camino a seguir si los datos de origen no son trivialmente grandes y / o necesita hacer mucho este tipo de cosas en su aplicación. Sospecho firmemente que el plan de consulta para la solución de Aaron no escalará bien a medida que aumente el tamaño de entrada. (Intenté agregar un índice a la tabla temporal, pero eso no ayudó).
Esta solución, como muchas otras cosas, es una compensación:
EDITAR: Bueno, fui a tratar de ver si esto era realmente mejor, y resulta que el requisito de que los comentarios estén en un orden específico actualmente no es posible satisfacerlos usando una función agregada. :(
Ver SqlUserDefinedAggregateAttribute.IsInvariantToOrder . Básicamente, lo que debe hacer es
OVER(PARTITION BY customer_code ORDER BY row_num)
peroORDER BY
no se admite en laOVER
cláusula al agregar. Supongo que agregar esta funcionalidad a SQL Server abre una lata de gusanos, porque lo que debería cambiarse en el plan de ejecución es trivial. El enlace mencionado anteriormente dice que está reservado para uso futuro, por lo que esto podría implementarse en el futuro (sin embargo, en 2005 probablemente no tenga suerte).Esto podría todavía ser realizado por el embalaje y analizar el
row_num
valor agregado en la cadena, y luego hacer el tipo dentro del objeto CLR ... que parece bastante hacker.En cualquier caso, a continuación se muestra el código que usé en caso de que alguien más lo encuentre útil, incluso con la limitación. Dejaré la parte de piratería como un ejercicio para el lector. Tenga en cuenta que utilicé AdventureWorks (2005) para los datos de prueba.
Asamblea agregada:
T-SQL para probar (
CREATE ASSEMBLY
ysp_configure
para habilitar CLR omitido):fuente
Aquí hay una solución basada en el cursor que garantiza el orden de los comentarios
row_num
. (Vea mi otra respuesta sobre cómo se[dbo].[Comments]
rellenó la tabla).fuente
fuente