2011-10-13 7 views
10

tengo una tabla como:valores de fila Combinar en un archivo CSV (aka GROUP_CONCAT para SQL Server)

EntityID AttributeID OptionText 
5016  20   Paintings 
5044  18   Female 
5060  48   M 
5060  48   F 
5060  49   Apple 
5060  49   Banana 
5060  49   Cat 

que quiero crear una vista que se mostrará:

5016 20 Paintings 
5044 18 Female 
5060 48 M,F 
5060 49 Apple, Banana, Cat 

se entienden los valores de atributos en cada entidad se debe mostrar separada por una coma.

El número de opciones puede variarse.

¡Se agradece cualquier ayuda!

Respuesta

11

Para cada par de EntityID, AttributeID usar el truco vía de acceso XML para generar el CSV

SELECT 
    M.EntityID, M.AttributeID, 
    SUBSTRING(CAST(foo.bar AS varchar(8000)), 2, 7999) AS Options 
FROM 
    (
    SELECT DISTINCT EntityID, AttributeID 
    FROM MyTable 
    ) M 
    CROSS APPLY 
    (
    SELECT 
     ',' + OptionText 
    FROM 
     MyTable M2 
    WHERE 
     M.EntityID = M2.EntityID AND M.AttributeID= M2.AttributeID 
    FOR XML PATH ('') 
    ) foo(bar) 
+0

¿Habría alguna diferencia de rendimiento notable entre 'SUBSTRING' y' CAST' contra 'STUFF ((...), 1, 2, '')'? – Seph

+0

@Seph: marginal, no sé en qué dirección. La mayor parte de los recursos y el tiempo serán los JOIN y el procesamiento XML. No eliminando la primera coma. – gbn

+0

Gracias por resolver la consulta, pero todavía estoy enfrentando problemas de rendimiento. La mesa va a tener más de 1 millón de registros. En este caso, incluso para recuperar solo algunos registros, el tiempo empleado es de más de 2 segundos. – Moons

4

Pruebe el código de abajo (he incluido toda SQL de prueba para que no tiene que practicar en datos en tiempo real). Puede ver un ejemplo de trabajo aquí: http://data.stackexchange.com/stackoverflow/q/115141/

--Set up test table 
CREATE TABLE #Table1 (EntityID INT, AttributeID INT, OptionText VARCHAR(50)) 

INSERT INTO #Table1 
SELECT 5030, 48, 'M' 

INSERT INTO #Table1 
SELECT 5030, 48, 'F' 

--Begin actual working SQL   
SELECT  T1.EntityID, 
      T1.AttributeID, 
      STUFF((SELECT ', ' + T2.OptionText 
        FROM  #Table1 T2 
        WHERE  T2.AttributeID = T1.AttributeID 
        AND  T2.EntityID = T1.EntityID 
        FOR XML PATH('') 
       ), 1, 2, '') [Attributes] 
FROM  #Table1 T1 
GROUP BY T1.EntityID, T1.AttributeID 

DROP TABLE #Table1 
+0

La consulta es muy útil, pero todavía tengo problemas de rendimiento. La mesa va a tener más de 1 millón de registros. En este caso, incluso para recuperar solo algunos registros, el tiempo empleado es de más de 2 segundos. ¿Hay alguna alternativa para esto? – Moons

+0

Esta consulta es lo que estaba buscando, gracias –

Cuestiones relacionadas