2011-08-06 7 views
5

Tengo una tabla que tiene varios campos de fecha. Por ejemplo, en la tabla de defectos, tengo lo siguiente: dateAssigned, dateCompleted, dateResolved. Estoy tratando de conseguir una consulta que resume los defectos como tal:Consulta SQL que agrupa varios campos de fecha

  | Number Assigned | Number Completed | Number Resolved 
-----------------------------+------------------+----------------- 
    Mar-2011 |  33   |  22  |  33   
    Apr-2011 |  10   |  11  |  22 
    May-2011 |  22   |  66  |  46 

etc

he llegado con la siguiente fue en vano:

SELECT year(d.dateAssigned) 
     ,month(d.dateAssigned) 
     ,COUNT(d.dateAssigned) 
     ,COUNT(d.dateCompleted) 
     ,COUNT(d.dateResolved) 
    FROM defect d 
    GROUP BY year(d.dateAssigned), month(d.dateAssigned) 
    ORDER BY year(d.dateAssigned), month(d.dateAssigned) 

Esto funciona correctamente para resumir la FechaDefectos firmados, pero no para los demás. Me doy cuenta de que esto probablemente se deba al hecho de que estoy agrupando por fecha de firma, pero no sé cómo hacerlo.

Cualquier ayuda sería apreciada.

+0

no veo una manera elegante, pero podrías unir tres sub-selecciones diferentes, agrupadas para cada una por turno. con suerte alguien publicará algo mejor. –

Respuesta

1

Esta es una forma de hacerlo.

SELECT YEAR(typedate), 
     MONTH(typedate), 
     SUM(CASE 
      WHEN TYPE = 'assinged' THEN 1 
      ELSE 0 
      END) number_assigned, 
     SUM(CASE 
      WHEN TYPE = 'completed' THEN 1 
      ELSE 0 
      END) number_completed, 
     SUM(CASE 
      WHEN TYPE = 'Resolved' THEN 1 
      ELSE 0 
      END) number_resolved 
FROM (SELECT dateassigned typedate, 
       'assinged' AS TYPE 
     FROM sampledata 
     WHERE dateassigned IS NOT NULL 
     UNION ALL 
     SELECT datecompleted typedate, 
       'completed' AS TYPE 
     FROM sampledata 
     WHERE datecompleted IS NOT NULL 
     UNION ALL 
     SELECT dateresolved typedate, 
       'Resolved' AS TYPE 
     FROM sampledata 
     WHERE dateresolved IS NOT NULL) data 
GROUP BY YEAR(typedate), 
      MONTH(typedate) 
ORDER BY YEAR(typedate), 
      MONTH(typedate) 

El sub seleccione crea dos columnas typedate y el tipo

Qué tendrá este aspecto

typedate type 
-------- --------- 
1/1/2011 assinged 
1/1/2011 assinged 
1/1/2011 assinged 
2/1/2011 completed 
2/1/2011 completed 
2/3/2011 Resolved 

Luego usé SUM(CASE... para pivotar los datos. Si estás utilizando un RDBMS que lo soporta se puede utilizar en lugar pivot

El resultado final se ve algo como esto

     Number_Assigned Number_completed Number_Resolved 
----------- ----------- --------------- ---------------- --------------- 
2011  1   3    0    0 
2011  2   0    2    1 

Lo dejo a usted para hacer el formato del año y el mes

+0

¡Esto hizo el truco! Muchas gracias ... Tengo mucho que aprender. – j0nnyf1ve

0

Otra forma sería crear una tabla months con campos: year, month, firstDate, nextMonthFirstDate, ya sea sobre la marcha o como tabla temporal o como tabla permanente (tener una tabla almacenada con 100 años y filas de 100x12 no ocupará mucho espacio y puede a mano en otras consultas) y use algo como esto (que es equivalente a monthsLEFT JOIN ed tres veces a la mesa defect):

SELECT 
    (SELECT COUNT(*) 
     FROM defect AS d 
     WHERE m.firstDate <= d.dateAssigned 
     AND d.dateAssigned < m.nextMonthFirstDate 
    ) AS Number_Assigned 
    . (SELECT COUNT(*) 
     FROM defect AS d 
     WHERE m.firstDate <= d.dateCompleted 
     AND d.dateCompleted < m.nextMonthFirstDate 
    ) AS Number_Completed 
    . (SELECT COUNT(*) 
     FROM defect AS d 
     WHERE m.firstDate <= d.dateResolved 
     AND d.dateResolved < m.nextMonthFirstDate 
    ) AS Number_Resolved 
FROM months AS m 
ORDER BY m.year 
     , m.month 
2
SELECT year(defectDate), month(defectDate), SUM(assigned), SUM(resolved), SUM(completed) 
    FROM (
    SELECT d.dateAssigned AS defectDate, 1 AS assigned, 0 AS resolved, 0 AS completed 
     FROM defect d 
    UNION ALL 
    SELECT d.dateCompleted AS defectDate, 0 AS assigned, 1 AS resolved, 0 AS completed 
     FROM defect d 
    UNION ALL 
    SELECT d.dateResolved AS defectDate, 0 AS assigned, 0 AS resolved, 1 AS completed 
     FROM defect d 
) 
    GROUP BY year(defectDate), month(defectDate) 
    ORDER BY year(defectDate), month(defectDate) 
1
SELECT year(d.dateAssigned) 
     ,month(d.dateAssigned) 
     ,COUNT(d.dateAssigned) 
     ,(SELECT count(*) 
     FROM defect as dc 
     WHERE month(dc.dateCompleted) = month(d.dateAssigned) and 
       year(dc.dateCompleted) = year(d.dateAssigned)) 
     ,(SELECT count(*) 
     FROM defect as dr 
     WHERE month(dr.dateResolved) = month(d.dateAssigned) and 
       year(dr.dateResolved) = year(d.dateAssigned)) 
FROM defect d 
GROUP BY year(d.dateAssigned), month(d.dateAssigned) 
-1

Esto es posible si utilizamos grupo en el caso de los alias

SELECT CASE 
     WHEN (year(Challan_Date) is null or year(TAX_INVOICE_Date)!=null) THEN year(TAX_INVOICE_Date) 
     WHEN (year(Challan_Date) != null or year(TAX_INVOICE_Date) is null) THEN YEAR(Challan_Date) 
     WHEN (year(Challan_Date) is null or year(TAX_INVOICE_Date)is null) THEN 'NA' 
     WHEN (year(Challan_Date) != null or year(TAX_INVOICE_Date)!= null) THEN year(Challan_Date) 
     ELSE year(TAX_INVOICE_Date) END as Dates_Record, TAX_INVOICE_Date, Challan_Date 
FROM TransactionRecords 
Cuestiones relacionadas