SQL Как сгруппировать данные по 2 различным столбцам даты? - PullRequest
1 голос
/ 06 мая 2011

У меня есть такой стол:

    Id     Date1          Date2     Status
    ----------------------------------------------
     1    01/01/2010     null         A
     2    04/04/2010      05/14/10    X
     3    01/01/2010     null         A
     4    01/11/2010      01/01/2010  X
     5    01/02/2010     null         A

И некоторые другие записи, Дата 1 не является нулевой, но она имеет значение только в группе, если Статус имеет значение А, для записей, где Дата2 не является нулевой, независимо от статуса, которым должна быть группа к этой дате2.

Требуемый набор результатов выглядит следующим образом:

 Date             Number of A Status        Number of Date 2 not null statuses
------------------------------------------------------------------------------
 01//01/2010            2                                     1
 01/02/2010             1                                     0
 05/14/2010             0                                     1 

По сути, группировка по группам по дате, проблема в том, что в некоторых случаях это для столбца Date1, а в другом - для столбцов Date2. Как это можно сделать?

Ответы [ 3 ]

2 голосов
/ 06 мая 2011

Вы можете группировать по выражению декодирования или регистру. Пробовал только в Oracle, поэтому не уверен, что это переносимо. С этими данными:

create table t42 as
select 1 id, to_date('01/01/2010') date1, null date2, 'A' status from dual
union select 2, to_date('04/04/2010'), to_date('05/14/2010'), 'X' from dual
union select 3, to_date('01/01/2010'), null, 'A' from dual
union select 4, to_date('01/11/2010'), to_date('01/01/2010'), 'X' from dual
union select 5, to_date('01/02/2010'), null, 'A' from dual
/

select * from t42;

ID                     DATE1                     DATE2                     STATUS
---------------------- ------------------------- ------------------------- ------
1                      01/01/2010                                          A     
2                      04/04/2010                05/14/2010                X     
3                      01/01/2010                                          A     
4                      01/11/2010                01/01/2010                X     
5                      01/02/2010                                          A

Вы можете сделать:

select case when date2 is null and status = 'A' then date1
        else date2 end as "Date",
    sum(case when status = 'A' then 1 else 0 end) as "Number of A status",
    sum(case when date2 is null then 0 else 1 end) as "Number of Date 2 null"
from t42
group by case when date2 is null and status = 'A' then date1 else date2 end
order by 1;

Что дает:

Date                      Number of A status     Number of Date 2 null  
------------------------- ---------------------- ---------------------- 
01/01/2010                2                      1                      
01/02/2010                1                      0                      
05/14/2010                0                      1
1 голос
/ 06 мая 2011

Это типичный запрос PIVOT:

   SELECT x.date,
          SUM(CASE WHEN 'A' IN (y.status, z.status) THEN 1 ELSE 0 END) AS NumStatusA,
          SUM(CASE 
                WHEN y.date2 IS NOT NULL OR z.date2 IS NOT NULL THEN 1 
                ELSE 0 
              END) AS NumDate2NotNull
     FROM (SELECT a.date1 AS date
             FROM YOUR_TABLE a
           UNION 
           SELECT b.date2 AS date
             FROM YOUR_TABLE b) x
LEFT JOIN YOUR_TABLE y ON y.date1 = x.date
LEFT JOIN YOUR_TABLE z ON z.date1 = x.date
 GROUP BY x.date

Но вам нужно создать таблицу, содержащую даты из обоих столбцов, основываясь на ваших данных, чтобы присоединиться к первому.

0 голосов
/ 06 мая 2011

Может быть, что-то вроде этого:

SELECT DISTINCT Date1 as Date,
(SELECT COUNT(*) FROM MyTable WHERE DATE1=MyT.Date1 AND Status = 'A') NumberAStatus,
(SELECT COUNT(*) FROM MyTable WHERE DATE1=MyT.Date1 AND Date2 is not null) NotNullDate2

FROM MyTable MyT
...