Как сделать динамический пивот с датой и еще одним столбцом в Oracle? - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть такая таблица:

 NAME          VALUE       IDENTIFIER          MYDATE
NAME1           123           ATR            01/10/2018  
NAME1           333           QTDE           01/10/2018  
NAME2           212           ATR            01/08/2018  
NAME2           123           QTDE           01/08/2018 
NAME2           133           ATR            01/09/2018  
NAME2           123           QTDE           01/09/2018  
NAME3           678           ATR            01/08/2018  
NAME3           123           QTDE           01/08/2018 

В IDENTIFIER это будет только ATR или QTDE.
Мне нужно сделать разворот, чтобы получить VALUE из QTDE или ATR каждого месяца, поэтому результат будет примерно таким:

NAME        QTDE08/2018        ATR08/2018        QTDE09/2018        ATR09/2018        QTDE10/2018        ATR10/2018
NAME1           0                   0               0                   0                 333                123
NAME2          123                 212             123                 133                 0                  0
NAME3          123                 678              0                   0                  0                  0

Я пытался сделать сводку, но я мог сделать только с IDENTIFIER, и я понятия не имею, как сделать это с датой

SELECT *
  FROM (SELECT ST.NAME,
               ST.VALUE,
               ST.IDENTIFIER,
               TO_CHAR(TO_DATE(ST.MYDATE), 'MM/YYYY') AS MYDATE
          FROM SOME_TABLE ST
         WHERE ST.IDENTIFIER IN ('QTDE', 'ATR')) 
PIVOT(SUM(VALUE)
      FOR IDENTIFIER IN ('QTDE' AS QTDE,
                         'ATR' AS ATR))

Я редактирую имя таблицы и столбцов, это не оригинальное имя из моей таблицы.

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

приведенный ниже пример должен быть переписан в Oracle и соответствовать вашему требованию.

CREATE TABLE Project(PRJ_ID int, UDN_ID INT, TXT_VALUE varchar(100));

INSERT INTO Project VALUES (8344,82,'E S'),(8344,69,'A M'),(8364,82,'End'),(8364,59,'Internal');

DECLARE @columns NVARCHAR(MAX), @columns1 NVARCHAR(MAX), @sql NVARCHAR(MAX);

--selecting distinct values and concatenating to get a result like [82],[69],[82]...


SELECT @columns1 = STUFF((
            SELECT DISTINCT ',' + '['+ CAST(UDN_ID AS VARCHAR) + ']' FROM Project
            FOR XML PATH('')
            ), 1, 1, '')
FROM Project;


--using that dynamic column string in the pivot query string


SET @sql = 'SELECT PRJ_ID,' + @columns1 + ' FROM
(
  SELECT * FROM Project
) AS src
PIVOT
(
  MAX(TXT_VALUE) FOR src.UDN_ID IN ('+ @columns1
  + ')
) AS p;';


--executing the pivot query


EXEC sp_executesql @sql;
0 голосов
/ 10 апреля 2019

Вы пытаетесь конвертировать 2 столбца даты и идентификатора, поэтому вам нужно 2 пивота. Пожалуйста, попробуйте ниже запрос, он должен работать. Не стесняйтесь возвращаться в случае каких-либо запросов. Это работает в оракуле, но не уверен, если вы пытаетесь в любой другой DBMS.

select * from (
select * from (
with all_data as 
(select 'NAME1' fname, 123 value, 'ATR' identif, '01-OCT-2018' mydate from dual union all
select 'NAME1' fname, 333 value, 'QTDE' identif, '01-OCT-2018'  mydate from dual union all
select 'NAME2' fname, 212 value, 'ATR' identif, '01-AUG-2018'  mydate from dual union all
select 'NAME2' fname, 123 value, 'QTDE' identif, '01-AUG-2018'  mydate from dual union all
select 'NAME2' fname, 133 value, 'ATR' identif, '01-SEP-2018'  mydate from dual union all
select 'NAME2' fname, 123 value, 'QTDE' identif, '01-SEP-2018'  mydate from dual union all
select 'NAME3' fname, 678 value, 'ATR' identif, '01-AUG-2018'  mydate from dual union all
select 'NAME3' fname, 123 value, 'QTDE' identif, '01-AUG-2018'  mydate from dual )
select identif,fname,value,mydate from  all_data)
pivot 
(
sum(value)
for mydate in ('01-AUG-2018' as "AUG-2018",'01-SEP-2018' as "SEP-2018",'01-OCT-2018' as "OCT-2018")))
pivot
(
sum("AUG-2018") "08-2018"
,sum("SEP-2018") "09-2018"
,sum("OCT-2018") "10-2018"
for identif in ('ATR' ATR,'QTDE' QTDE))
order by 1;
...