Подсчитать части общей стоимости в виде столбцов на строку (сводная таблица)

Я застрял с, казалось бы, простым запросом, но не смог заставить его работать в последние часы.

У меня есть стол files который содержит имена файлов и некоторые значения, такие как записи в этом файле, ДАТА создания (create_date), ДАТА обработки (processing_date) и так далее. Может быть несколько файлов для даты создания в разные часы, и вполне вероятно, что они не будут обработаны в один и тот же день создания, фактически для их обработки может потребоваться до трех дней или дольше.

Итак, давайте предположим, что у меня есть эти строки, в качестве примера:

create_date            | processing_date
------------------------------
2012-09-10 11:10:55.0  | 2012-09-11 18:00:18.0
2012-09-10 15:20:18.0  | 2012-09-11 13:38:19.0
2012-09-10 19:30:48.0  | 2012-09-12 10:59:00.0
2012-09-11 08:19:11.0  | 2012-09-11 18:14:44.0
2012-09-11 22:31:42.0  | 2012-09-21 03:51:09.0

В одном запросе я хочу получить усеченный сгруппированный столбец до дня create_date с 11 дополнительными столбцами для различий между processing_date и create_dateтак что результат должен выглядеть примерно так:

create_date   |   diff0days   | diff1days | diff2days | ... | diff10days
------------------------------------------------------------------------
2012-09-10    |       0             2           1       ...        0
2012-09-11    |       1             0           0       ...        1

и так далее, я надеюсь, вы поняли смысл:)

Я пробовал это, и до сих пор это работает, получая один агрегированный столбец для create_date с разницей - например - 3:

SELECT TRUNC(f.create_date, 'DD') as created, count(1) FROM files f WHERE TRUNC(f.process_date, 'DD') - trunc(f.create_date, 'DD') = 3 GROUP BY TRUNC(f.create_date, 'DD')

Я пытался объединить отдельные запросы и пробовал подзапросы, но это не помогло или, по крайней мере, моих знаний о SQL недостаточно.

Что мне нужно, так это подсказка, чтобы я мог включить различные различия в столбцы, как показано выше. Как я мог достичь этого?

3 ответа

Решение

Это в основном проблема поворота:

SELECT  TRUNC(f.create_date, 'DD') as created
,       sum(case TRUNC(f.process_date, 'DD') - trunc(f.create_date, 'DD')
                  when 0 then 1 end) as diff0days   
,       sum(case TRUNC(f.process_date, 'DD') - trunc(f.create_date, 'DD')
                  when 1 then 1 end) as diff1days   
,       sum(case TRUNC(f.process_date, 'DD') - trunc(f.create_date, 'DD')
                  when 2 then 1 end) as diff2days   
,       ...
FROM    files f 
GROUP BY 
        TRUNC(f.create_date, 'DD')
SELECT CreateDate,
    sum(CASE WHEN DateDiff(day, CreateDate, ProcessDate) = 1 THEN 1 ELSE 0 END) AS Diff1,
    sum(CASE WHEN DateDiff(day, CreateDate, ProcessDate) = 2 THEN 1 ELSE 0 END) AS Diff2,
    ...
FROM table
GROUP BY CreateDate
ORDER BY CreateDate

Поскольку вы используете Oracle 11g, вы также можете получить желаемый результат, используя pivot query,

Вот пример:

  -- sample of data from your question
  SQL> create table Your_table(create_date, processing_date) as
  2  (
  3        select '2012-09-10', '2012-09-11' from dual union all
  4        select '2012-09-10', '2012-09-11' from dual union all
  5        select '2012-09-10', '2012-09-12' from dual union all
  6        select '2012-09-11', '2012-09-11' from dual union all
  7        select '2012-09-11', '2012-09-21' from dual
  8   )
  9  ;

Table created



 SQL> with t2 as(
  2    select create_date
  3         , processing_date
  4         , to_date(processing_date, 'YYYY-MM-DD')  
                      - To_Date(create_date, 'YYYY-MM-DD') dif
  5      from your_table
  6    )
  7      select create_date
  8           , max(diff0) diff0
  9           , max(diff1) diff1
 10           , max(diff2) diff2
 11           , max(diff3) diff3
 12           , max(diff4) diff4
 13           , max(diff5) diff5
 14           , max(diff6) diff6
 15           , max(diff7) diff7
 16           , max(diff8) diff8
 17           , max(diff9) diff9
 18           , max(diff10) diff10
 19        from (select *
 20                from t2
 21                pivot(
 22                       count(dif)
 23                       for dif in ( 0 diff0
 24                                  , 1 diff1
 25                                  , 2 diff2
 26                                  , 3 diff3
 27                                  , 4 diff4
 28                                  , 5 diff5
 29                                  , 6 diff6
 30                                  , 7 diff7
 31                                  , 8 diff8
 32                                  , 9 diff9
 33                                  , 10 diff10
 34                                  )
 35                     ) pd
 36             ) res
 37      group by create_date
 38  ;

Результат:

Create_Date Diff0 Diff1 Diff2 Diff3 Diff4 Diff5 Diff6 Diff7 Diff8 Diff9 Diff10
-------------------------------------------------------------------------------- 
2012-09-10    0     2     1     0     0     0     0    0      0     0     0 
2012-09-11    1     0     0     0     0     0     0    0      0     0     1 
Другие вопросы по тегам