2011-07-06 15 views
11

Im utilizando el código de this MSDN page para crear un agregado definido por el usuario para concatenar cadenas con group by's en el servidor SQL. Uno de mis requisitos es que el orden de los valores concatenados sea el mismo que en la consulta. Por ejemplo:¿Se ha conservado el orden agregado de valores definidos por el usuario de SQL?

Value Group 
1  1 
2  1 
3  2 
4  2 

Usando consulta

SELECT 
    dbo.Concat(tbl.Value) As Concat, 
    tbl.Group 
FROM 
    (SELECT TOP 1000 
    tblTest.* 
    FROM 
    tblTest 
    ORDER BY 
    tblTest.Value) As tbl 
GROUP BY 
    tbl.Group 

consecuencia:

Concat Group 
"1,2" 1 
"3,4" 2 

El resultado parece venir siempre fuera correcto y como se esperaba, pero que me encontré con this page que indica que la orden no está garantizada y que el atributo SqlUserDefinedAggregateAttribute.IsInvariantToOrder solo está reservado para uso futuro.

Entonces mi pregunta es: ¿es correcto suponer que los valores concatenados en la cadena pueden terminar en cualquier orden?
Si ese es el caso, ¿por qué el código de ejemplo en la página de MSDN usa el atributo IsInvariantToOrder?

+0

No se puede responder a su pregunta MS, pero 'GROUP_CONCAT' le permite ser determinista sobre la concatenación. –

+0

@kerrek - tenga en cuenta que esto está etiquetado 'SQL Server' no' MySQL' – JNK

+0

Me temo que no hay 'GROUP_CONCAT' en SQL Server 2008 – Magnus

Respuesta

5

sospecho un gran problema aquí es su estado de "el mismo que en la consulta" - sin embargo, la consulta nunca define (y no se puede definir) una orden por las cosas que se agregan (se puede, por orden de curso grupos, teniendo un ORDER BY después del GROUP BY). Más allá de eso, solo puedo decir que se basa únicamente en un conjunto (en lugar de una secuencia ordenada), y que técnicamente el orden no está definido.

+0

+1 - Busque 'SQL Order' en SO y obtendrá muchas publicaciones sobre problemas similares. – JNK

+0

Puede especificar 'order by' si tiene una declaración' top' de una selección interna y de un grupo sobre eso. – Magnus

+0

@Marc He actualizado mi pregunta con una consulta que utiliza una selección interna con la instrucción 'top' y' order by'. ¿El resultado final de usar group by y 'Concat' en eso todavía tiene un orden indefinido? – Magnus

1

Si bien la respuesta aceptada es correcta, quería compartir una solución que otros pueden encontrarle útil. Advertencia: se trata de no usar ningún agregado definido por el usuario :)

El siguiente enlace describe una forma elegante de crear una lista concatenada y delimitada utilizando solo una instrucción SELECT y una variable varchar. La ventaja (para este hilo) es que puede especificar el orden en que se procesan las filas. El inconveniente es que no se puede concatenar fácilmente en muchos subconjuntos diferentes de filas sin una iteración dolorosa.

No es perfecto, pero para mi caso de uso fue una buena solución.

http://blog.sqlauthority.com/2008/06/04/sql-server-create-a-comma-delimited-list-using-select-clause-from-table-column/

+0

Aunque eso no se puede usar con un grupo como en mi pregunta. – Magnus

+0

Sí, exactamente - eso era lo que intentaba decir diciendo "el inconveniente es que ..." –

+0

¿Cómo se especifica un pedido en este caso? Si esto está dentro de una vista o función, aún es imposible especificar un orden, por lo que es inútil. –

Cuestiones relacionadas