【发布时间】:2018-09-05 18:10:28
【问题描述】:
我使用 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 和空单元格。如果两个日期中的任何一个都没有数据,我的查询不会返回任何内容。如果该日期没有值,如何使查询返回空单元格?
更新:我已经看到了带有数据透视的示例,但在我的情况下,不仅需要将列作为行,而且还需要从同一个表中查询不同日期的数据。此外,如果没有特定日期的日期,也不清楚如何获取空单元格。
【问题讨论】:
-
这是一个枢轴问题。阅读:modern-sql.com/use-case/pivot
-
谢谢。但是如何更轻松地解决两个不同日期的问题?
-
@S.T.第一步 - 取消透视,保留日期,第二步 - 按日期返回分组
-
@Dmitry 有什么小例子吗?
标签: sql oracle plsql oracle-xe