我使用Oracle 11 XE并拥有下表:
CREATE TABLE tst
(val_a NUMBER,
val_b NUMBER,
val_c NUMBER,
val_sum NUMBER,
id NUMBER,
dt DATE)
一些示例数据:
INSERT INTO tst
VALUES(12,15,17,44,1,TO_DATE('2018-03-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'));
INSERT INTO tst
VALUES(14,16,11,41,1,TO_DATE('2018-03-03 00:00:00', 'YYYY-MM-DD HH24:MI:SS'));
INSERT INTO tst
VALUES(6,7,8,21,2,TO_DATE('2018-03-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'));
我需要指定两个日期并获得以下结果(NEW_VAL
为SUM
,A
,B
和C
ID=1 and DT=2018-03-03
},OLD_VAL
是ID=1 and DT=2018-03-01
)的值:
ID X NEW_VAL OLD_VAL
--- --- --------- --------
1 SUM 41 44
A 14 12
B 16 15
C 11 17
以下是我已实施的查询:
select id, x, new_val, old_val from(
select tst_new.id id0, 1, tst_new.id, 'SUM' x, tst_new.val_sum new_val, tst_old.val_sum old_val from tst tst_new,
(select * from tst where dt=to_date('01.03.2018', 'dd.mm.yyyy')) tst_old
where tst_new.dt=to_date('03.03.2018', 'dd.mm.yyyy') and tst_new.id = tst_old.id and tst_new.id = 1
UNION ALL
select tst_new.id, 2, null, 'A', tst_new.val_a, tst_old.val_a from tst tst_new,
(select * from tst where dt=to_date('01.03.2018', 'dd.mm.yyyy')) tst_old
where tst_new.dt=to_date('03.03.2018', 'dd.mm.yyyy') and tst_new.id = tst_old.id and tst_new.id = 1
UNION ALL
select tst_new.id, 3, null, 'B', tst_new.val_b, tst_old.val_b from tst tst_new,
(select * from tst where dt=to_date('01.03.2018', 'dd.mm.yyyy')) tst_old
where tst_new.dt=to_date('03.03.2018', 'dd.mm.yyyy') and tst_new.id = tst_old.id and tst_new.id = 1
UNION ALL
select tst_new.id, 4, null, 'C', tst_new.val_c, tst_old.val_c from tst tst_new,
(select * from tst where dt=to_date('01.03.2018', 'dd.mm.yyyy')) tst_old
where tst_new.dt=to_date('03.03.2018', 'dd.mm.yyyy') and tst_new.id = tst_old.id and tst_new.id = 1
order by 1, 2
)
它确实提供了所需的结果,但看起来很糟糕。有没有办法让这个结果更容易?
此外,如果特定日期没有数据,结果应包含ID,X和空单元格。如果两个日期中没有任何数据,我的查询只返回任何内容。如果该日期没有值,如何使查询返回空单元格?
更新:我已经看过使用数据透视的示例,但在我的情况下,不仅需要列作为行,还要查询同一表中不同日期的数据。此外,如果没有特定日期的日期,也不清楚如何获取空单元格。
答案 0 :(得分:1)
内部子查询是unpivot的结果,外部 - 向后旋转:
select *
from (select to_char(dt, 'dd.mm.yyyy') dt, vals, dt_vals from tst
unpivot (dt_vals for vals in (val_a, val_b, val_c, val_sum)))
pivot (sum(dt_vals) for dt in ('01.03.2018', '03.03.2018'))
order by 1
VALS '01.03.2018' '03.03.2018'
------- ------------ ------------
VAL_A 18 14
VAL_B 22 16
VAL_C 25 11
VAL_SUM 65 41
接下来,您需要指定如何过滤这些值的规则:
NEW_VAL
是值SUM
,A
B
和C
ID = 1 and DT = 2018-03-03
,OLD_VAL
是{{1}的值}}
我只是硬编码了#34;按照":
ID = 1 and DT = 2018-03-01