Oracle-返回范围内每个日期的列
假设我有表A:援助Oracle-返回范围内每个日期的列,oracle,date,pivot,Oracle,Date,Pivot,假设我有表A:援助 PersonID Date CHECK 123456 2012-01-01 F 213415 2012-01-03 A PersonID ArrivalDate Jan-01 Jan-02 Jan-03 123456 2012-01-01 F NULL NULL 213415
PersonID Date CHECK
123456 2012-01-01 F
213415 2012-01-03 A
PersonID ArrivalDate Jan-01 Jan-02 Jan-03
123456 2012-01-01 F NULL NULL
213415 2012-01-03 NULL NULL A
该系统用于检查,检查时间为1至15天,但不得超过15天。如果您有任何想法,我将不胜感激。您可以试试这个,但我不确定这是否是您需要的
with inputs_
as (select 123456 person_id, to_date('2012-01-01', 'YYYY-MM-DD') date_, 'F' check_
from dual
union all
select 213415 person_id, to_date('2012-01-03', 'YYYY-MM-DD'), 'A' check_
from dual
UNION ALL
select 123456 person_id, to_date('2012-01-01', 'YYYY-MM-DD') date_, 'F' check_
from dual
union all
select 213415 person_id, to_date('2012-01-03', 'YYYY-MM-DD'), 'A' check_
from dual
union all
select 123456 person_id, to_date('2012-01-04', 'YYYY-MM-DD') date_, 'F' check_
from dual
union all
select 213415 person_id, to_date('2012-01-05', 'YYYY-MM-DD'), 'A' check_
from dual
union all
select 123456 person_id, to_date('2012-01-02', 'YYYY-MM-DD') date_, 'A' check_
from dual
union all
select 213415 person_id, to_date('2012-01-04', 'YYYY-MM-DD'), 'A' check_
from dual
UNION ALL
select 213415 person_id, to_date('2012-01-02', 'YYYY-MM-DD'), 'F' check_
from dual)
select *
from (select person_id, date_ arrival_date, check_, TO_CHAR(date_, 'DD-MON') date_
from inputs_)
pivot (min(check_) for date_ in ('01-JAN', '02-JAN', '03-JAN', '04-JAN', '05-JAN')
)
order by 2;
输出:
而且这不是动态的,所以如果您想要动态透视,您可以看到这个链接,您可以使用查询为透视的IN子句构造最小日期到最大日期范围内的动态日期值。然后在PIVOT的in子句中打开一个带有所需参数的动态游标。 DBMS_SQL.RETURN_RESULT 12c及更高版本将显示所需的结果。 对于旧版本,您可以在此处参考我的答案,以便轻松显示光标的输出:
在普通SQL中,只有在预先确定列数而不是在读取输入数据之后,并且列名及其顺序也必须事先知道的情况下,才能执行此操作。否则,您需要动态SQL advanced,而且通常不推荐这样做,或者您可以在报表应用程序中而不是在SQL中执行此操作—这是执行此类格式化的更好地方。
DECLARE
v_instring VARCHAR2 (1000);
v_cur SYS_REFCURSOR;
BEGIN
WITH dt ( min_t ,max_t ) AS
( SELECT MIN(Date_t) ,MAX(Date_t) FROM TableA
) ,
datevalues (date_ch) AS
(SELECT TO_CHAR(min_t + lvl - 1, 'DD-MON')
FROM dt CROSS APPLY
( SELECT LEVEL lvl FROM DUAL CONNECT BY LEVEL <= max_t - min_t + 1
)
)
SELECT LISTAGG(''''
|| date_ch
|| ''' AS "'
|| date_ch, '",') WITHIN GROUP (
ORDER BY date_ch )||'"'
INTO v_instring
FROM
( SELECT DISTINCT date_ch FROM datevalues
);
OPEN v_cur FOR 'select * from (select PersonID, date_t arrival_date, check_t,
TO_CHAR(date_t, ''DD-MON'') date_t from TableA) pivot ( min(check_t)
for date_t in ('||v_instring||')) ORDER BY arrival_date';
DBMS_SQL.RETURN_RESULT(v_cur);
END;
/
PERSONID ARRIVAL_DATE 01-JAN 02-JAN 03-JAN 04-JAN 05-JAN 06-JAN
------------- --------------- ------ ------ ------ ------ ------ ------
123456 01-01-12 F
213415 03-01-12 A
213416 04-01-12 F
345677 06-01-12 A