2009-03-20 16 views
5

Tengo una consulta que tiene este aspecto:filas en columnas y agrupación

SELECT OrganizationName, OrganizationID, ReceivableStatus, InvoiceFee 
FROM v_InvoicesFreelanceOutstanding 
ORDER BY OrganizationID 

Los datos de los que podría tener este aspecto:

 
OrganizationName OrganizationID  ReceivableStatus  InvoiceFee 
----------------------------------------------------------------------------- 
Company A      139  60-90 days     672.00 
Company A      139  60-90 days    1800.00 
Company A      139  over 90 days    1440.00 
Company B      264  Current     3559.38 
Company B      264  60-90 days    3785.50 
Company C      271  60-90 days     446.25 
Company C      271  over 90 days    637.50 
Company C      271  over 90 days    1126.25 

Lo que quiero con el tiempo de visualización es algo como esto (para los datos anteriores):

 
Company  Current 30-60 days 60-90 days over 90 days  Total 
----------------------------------------------------------------------------- 
Company A   0    0  2472.00    0  2472.00 
Company B 3559.38    0  3785.50    0  7344.88 
Company C   0    0  446.25   1763.75  2210.00 

My SQL-fu no es suficiente para que me pasado este

:
SELECT 
    MAX(OrganizationName) as OrganizationName, 
    OrganizationID, 
    ReceivableStatus, 
    SUM(InvoiceFee) as TotalDue 
FROM v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationID, ReceivableStatus 

Cuál muestra algo como esto (de nuevo, a partir de los datos anteriores):

 
OrganizationName OrganizationID  ReceivableStatus   TotalDue 
----------------------------------------------------------------------------- 
Company A      139  60-90 days    2472.00 
Company A      139  over 90 days    1440.00 
Company B      264  Current     3559.38 
Company B      264  60-90 days    3785.50 
Company C      271  60-90 days     446.25 
Company C      271  over 90 days    1763.75 

¿Qué, pues? Cualquier ayuda sería apreciada.

Tenga en cuenta que los estados que se muestran en la segunda tabla (Current, 30-60 days, 60-90 days, over 90 days) son los únicos que estoy esperando para llegar bajo ReceivableStatus.

EDIT: Lo siento por no incluir esto. Estoy al tanto de PIVOT pero no pude hacerlo para hacer lo que quiero.

Respuesta

2

Esto parece un trabajo para pivot si está utilizando SQL Server 2005 o posterior.

EDIT:

Dado que ya sabe sobre pivot, se sabe que lo hace prácticamente lo que necesita.

ya tiene la siguiente consulta:

SELECT 
    MAX(OrganizationName) as OrganizationName, 
    OrganizationID, 
    ReceivableStatus, 
    SUM(InvoiceFee) as TotalDue 
FROM v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationID, ReceivableStatus 

que le da la corriente, 30-60, 60-90 y más de 90 piezas que usted necesita. Si pivoteas eso, obtienes todo lo que necesitas excepto tu total. Así que acaba de lanzar en el total:

(SELECT 
    MAX(OrganizationName) as OrganizationName, 
    OrganizationID, 
    ReceivableStatus, 
    SUM(InvoiceFee) as TotalDue 
FROM v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationID, ReceivableStatus) 
UNION 
(SELECT 
    MAX(OrganizationName) as OrganizationName, 
    OrganizationID, 
    'Total' AS ReceivableStatus, 
    SUM(InvoiceFee) as TotalDue 
FROM v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationID) 

pivote en este resultado y usted debe obtener el resultado que quiere:

SELECT * 
FROM 
    [the query above] 
PIVOT (
    SUM(TotalDue) 
    FOR ReceivableStatus IN ([Current],[30-60 days],[60-90 days],[over 90 days],[Total]) 
) 
+0

que debería haber sido más claro; Estoy al tanto de PIVOT, simplemente no pude hacer que haga lo que necesito. –

+0

Soy un idiota. Mi primer intento en el PIVOT es lo que tiene, pero lo hice SUM (Factura) en lugar de SUM (TotalDue) en la cláusula PIVOT. Boohoo. Sin embargo, funciona Gracias. –

+0

Todos cometemos errores. Lo importante es que aprendamos de ellos. Me alegro de poder ayudar. – Welbog

3

PIVOT chupa. Tiene una sintaxis horrible y no es un PIVOT en el sentido de tabla dinámica, es decir, usted debe saber exactamente cuántas columnas se obtendrán por adelantado.

Probablemente sea más fácil hacer un informe de tabulación cruzada.

SELECT 
OrganizationName, 
OrganizationID, 
SUM(CASE WHEN ReceivableStatus  = '30-60 days' THEN InvoiceFee ELSE 0 END) AS [30 - 60 Days], 
SUM(CASE WHEN ReceivableStatus  = '60-90 days' THEN InvoiceFee ELSE 0 END) AS [60 - 90 Days], 
SUM(CASE WHEN ReceivableStatus  = '90-120 days' THEN InvoiceFee ELSE 0 END) AS [90 - 120 Days] 

FROM 
v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationID 
+0

¿Cómo funcionaría esto con el GRUPO? Solo quiero mostrar el SUM (Factura) de 30-60 días en la columna de 30-60 días, y así sucesivamente. –

+0

Y sabré cuántas columnas se obtendrán por adelantado, así que estoy de acuerdo con PIVOT si hace el trabajo, aunque la sintaxis me está haciendo doler la cabeza. –

1

No he utilizado antes de pivote, por lo que puede ser su respuesta, pero he utilizado la fuerza bruta en un problema como este en el pasado y para usted que sería algo como:

SELECT OrganizationName, SUM(Current) AS Current, SUM(3060Days) AS 3060Days, SUM(6090Days) AS 6090Days, SUM(Over90Days) As Over90Days, SUM(Total) AS Total 
FROM 
(
SELECT 
    OrganizationName, 
    CASE WHEN ReceivableStatus = 'Current' THEN 
     SUM(InvoiceFee) 
    ELSE 
     0 
    END AS Current, 
    CASE WHEN ReceivableStatus = '30-60 days' THEN 
     SUM(InvoiceFee) 
    ELSE 
     0 
    END AS 3060Days, 
    CASE WHEN ReceivableStatus = '60-90 days' THEN 
     SUM(InvoiceFee) 
    ELSE 
     0 
    END AS 6090Days, 
    CASE WHEN ReceivableStatus = 'over 90 days' THEN 
     SUM(InvoiceFee) 
    ELSE 
     0 
    END AS Over90Days, 
    SUM(InvoiceFee) AS Total 
FROM v_InvoicesFreelanceOutstanding 
GROUP BY OrganizationName, ReceivableStatus) temp 
GROUP BY OrganizationName 

Básicamente, la consulta interna le brinda resultados para cada organización y un total para cada categoría individual y la consulta externa los agrega a todos en filas únicas para cada organización. Nuevamente, esta puede no ser la forma más elegante o eficiente de ir, pero es una manera.

+0

+1. Aunque funcionó, es más grande de lo que esperaba y tengo el PIVOT funcionando. ¡Gracias, sin embargo! –

2

Bueno, aquí es otro pivote :)

 
SET NOCOUNT ON 

DECLARE @table TABLE 
( OrganizationName VARCHAR(20), 
    OrganizationID  INT, 
    ReceivableStatus VARCHAR(20), 
    InvoiceFee  FLOAT 
) 

INSERT INTO @table 
SELECT 'Company A',139,'60-90 days',672.00 UNION 
SELECT 'Company A',139,'60-90 days',1800.00 UNION 
SELECT 'Company A',139,'over 90 days',1440.00 UNION 
SELECT 'Company B',264,'Current',3559.38 UNION 
SELECT 'Company B',264,'60-90 days',3785.50 UNION 
SELECT 'Company C',271,'60-90 days',446.25 UNION 
SELECT 'Company C',271,'over 90 days',637.50 UNION 
SELECT 'Company C',271,'over 90 days',1126.25 

--Specify Just the fields you want to return 
;WITH COMPANYINFO(OrganizationName,OrganizationID,ReceivableStatus,InvoiceFee) AS 
    (
    SELECT OrganizationName, 
     OrganizationID, 
     ReceivableStatus, 
     InvoiceFee 
    FROM @Table AS b 
    ) 
    SELECT * 
    FROM COMPANYINFO 
    PIVOT 
     (
     SUM(InvoiceFee) 
     FOR ReceivableStatus 
     IN ([Current],[60-90 days],[over 90 days]) 
     ) 
    AS P 
    ORDER BY OrganizationName 
+0

Bien hecho. Gracias. –

Cuestiones relacionadas