Разделение данных за год с использованием SQL с помощью сводных точек - PullRequest
2 голосов
/ 26 сентября 2011

У меня возникли проблемы с выяснением того, как построить серию операторов SQL, чтобы разделить некоторые данные, которые у меня есть, на годичную основу. Есть n пунктов, у которых есть записанное количество за набор дней в течение стольких лет. Вот небольшой примерный макет основных данных, которые у меня есть.

   |========|==============|===========|
   | Name   | Date         | Quantity  |
   |========|==============|===========|
 1 | AAAAA  | 10-DEC-2008  | 5         |
 2 | AAAAA  | 11-DEC-2008  | 2         |
 3 | AAAAA  | 12-DEC-2008  | 0         |
 4 | AAAAA  | 09-DEC-2009  | 3         |
 5 | AAAAA  | 10-DEC-2009  | 2         |
 6 | AAAAA  | 11-DEC-2009  | 3         |
 7 | BBBBB  | 10-DEC-2008  | 5         |
 8 | BBBBB  | 11-DEC-2008  | 2         |
 9 | BBBBB  | 12-DEC-2008  | 0         |
10 | BBBBB  | 09-DEC-2009  | 3         |
11 | BBBBB  | 10-DEC-2009  | 1         |
12 | BBBBB  | 11-DEC-2009  | 0         |
   |========|==============|===========|

Мне нужно преобразовать это в таблицу, которая принимает форму.

   |========|==============|===============|===============|
   | Name   | Date         | Quantity 2008 | Quantity 2009 |
   |========|==============|===============|===============|
 1 | AAAAA  | 09-DEC       |               | 3             |
 2 | AAAAA  | 10-DEC       | 5             | 2             |
 3 | AAAAA  | 11-DEC       | 2             | 3             |
 4 | AAAAA  | 12-DEC       | 0             |               |
 5 | BBBBB  | 09-DEC       |               | 3             |
 6 | BBBBB  | 10-DEC       | 5             | 1             |
 7 | BBBBB  | 11-DEC       | 2             | 0             |
 8 | BBBBB  | 12-DEC       | 0             |               |
   |========|==============|===============|===============|

Следует предположить, что в базе данных есть тысячи именованных элементов, и начальные дни записи каждого года будут разными, например, 6 декабря 2010 г. и 5 декабря 2009 г.

Надеюсь, кто-то может помочь.

Ответы [ 3 ]

4 голосов
/ 26 сентября 2011

Если вы используете Oracle 11g , вы можете повернуть таблицу как:

select *
  from (    
    select name,
           to_char(theDate, 'DD-MON') as dayMonth,
           extract(year from thedate) as year,
           quantity
      from yourTable
) 
 pivot (sum(quantity) as quantity for (year) in (2008 as y2008, 2009 as y2009))
order by name, dayMonth;

, который возвращает следующее

NAME  DAYMONTH        Y2008_QUANTITY         Y2009_QUANTITY         
----- --------------- ---------------------- ---------------------- 
AAAAA 09-DEC                                 3                      
AAAAA 10-DEC          5                      2                      
AAAAA 11-DEC          2                      3                      
AAAAA 12-DEC          0                                        
BBBBB 09-DEC                                 3                      
BBBBB 10-DEC          5                      1                      
BBBBB 11-DEC          2                      0                      
BBBBB 12-DEC          0                                           

8 rows selected
2 голосов
/ 26 сентября 2011

До Oracle11 вы можете использовать этот стандартный трюк:

SQL> create table mytable (name,mydate,quantity)
  2  as
  3  select 'AAAAA', date '2008-12-10', 5 from dual union all
  4  select 'AAAAA', date '2008-12-11', 2 from dual union all
  5  select 'AAAAA', date '2008-12-12', 0 from dual union all
  6  select 'AAAAA', date '2009-12-09', 3 from dual union all
  7  select 'AAAAA', date '2009-12-10', 2 from dual union all
  8  select 'AAAAA', date '2009-12-11', 3 from dual union all
  9  select 'BBBBB', date '2008-12-10', 5 from dual union all
 10  select 'BBBBB', date '2008-12-11', 2 from dual union all
 11  select 'BBBBB', date '2008-12-12', 0 from dual union all
 12  select 'BBBBB', date '2009-12-09', 3 from dual union all
 13  select 'BBBBB', date '2009-12-10', 1 from dual union all
 14  select 'BBBBB', date '2009-12-11', 0 from dual
 15  /

Table created.

SQL> select name
  2       , to_char(mydate,'dd-MON')
  3       , sum(case extract(year from mydate) when 2008 then quantity end) quantity_2008
  4       , sum(case extract(year from mydate) when 2009 then quantity end) quantity_2009
  5    from mytable
  6   group by name
  7       , to_char(mydate,'dd-MON')
  8   order by name
  9       , to_char(mydate,'dd-MON')
 10  /

NAME  TO_CHA QUANTITY_2008 QUANTITY_2009
----- ------ ------------- -------------
AAAAA 09-DEC                           3
AAAAA 10-DEC             5             2
AAAAA 11-DEC             2             3
AAAAA 12-DEC             0
BBBBB 09-DEC                           3
BBBBB 10-DEC             5             1
BBBBB 11-DEC             2             0
BBBBB 12-DEC             0

8 rows selected.

С уважением,
Роб.

2 голосов
/ 26 сентября 2011

Примерно так должно работать:

SELECT
    Name, FormattedDate, SUM(Quantity_2008), SUM(Quantity_2009)
FROM
(
SELECT
    Name,
    ConvertDateToDayMonthRepresentation(YourDate) as FormattedDate,
    DECODE(EXTRACT(YEAR FROM YourDate), 2008, Quantity, 0) as Quantity_2008, 
    DECODE(EXTRACT(YEAR FROM YourDate), 2009, Quantity, 0) as Quantity_2009
FROM
    YourTable
)
GROUP BY Name, FormattedDate;

Обратите внимание:

  1. Вам нужно добавлять код для каждого нужного года - в вашем запросе не может быть динамических столбцов.
  2. ConvertDateToDayMonthRepresentation - это пользовательская функция, которая должна преобразовывать дату в строковое представление дня и месяца без года. Создать тривиально с помощью EXTRACT.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...