我遇到了一个查询问题,它会依次变成多个视图和一个完整的过程 生成一个表来显示从一天到下一天的差异。 说实话,在SQL Server下,我可以通过一个查询完成此任务。 但是,在Oracle 11g下,做同样的事情并且最重要的是查询是非常困难的 运行速度非常慢。现在运行我的查询需要超过5分钟,并且它没有工作。
我有一张数据表
DATE SERVICE ENV RESPONSES
15-NOV-2016 PROD T1 4793
15-NOV-2016 PROD U1 3245
15-NOV-2016 PROD X1 4984
14-NOV-2016 PROD T1 5812
14-NOV-2016 PROD U1 3918
14-NOV-2016 PROD X1 3282
13-NOV-2016 PROD T1 11231
13-NOV-2016 PROD U1 1564
13-NOV-2016 PROD X1 2816
注意:此数据可追溯到几年,涵盖6个环境
对于报告,我需要生成一个如下所示的结果集
DATE ENV T1 U1 X1 TOTAL VARIANCE
20161115 PROD 4793 3245 4984 14022 +7.76%
20161114 PROD 5812 3918 3282 13012 -16.65%
20161113 PROD 11231 1564 2816 15611 +9.13%
当差异大于+/- 10%
时,此报告会消失此外,只想发送3-5行,而不是整个视图。 我尝试使用分区,但它使我的查询速度变慢,并且没有生成所需的数据。
该设计目前涉及创建6个单独的视图以加入主表以转动数据 但是,我似乎无法使查询正确生成方差。 方差计算为((当前日期总数/昨天的总数) - 1)* 100 或((13012/15611) - 1.00)x 100 = -16.65
每个视图
CREATE OR REPLACE FORCE VIEW USAGE_T1
(
DATEREF,
REALM,
TOTAL
)
AS
SELECT DATE, ENV, TOTAL
FROM USAGE_COUNT
WHERE ENV = 'T1';
此查询构建表,但缺少方差
SELECT
TO_CHAR(base.ENDDATE, 'YYYYMMDD') AS DATEREF
, base.ENV
, T1.TOTAL AS "T1"
, U1.TOTAL AS "U1"
, X1.TOTAL AS "X1"
, NVL(T1.TOTAL, 0) + NVL(U1.TOTAL,0) + NVL(X1.TOTAL,0) AS "TOTAL"
FROM USAGE base
LEFT JOIN USAGE_T1 T1
ON T1.DATEREF = TO_CHAR(base.ENDDATE, 'YYYYMMDD')
LEFT JOIN USAGE_U1 U1
ON U1.DATEREF = TO_CHAR(base.ENDDATE, 'YYYYMMDD')
LEFT JOIN USAGE_X1 X1
ON X1.DATEREF = TO_CHAR(base.ENDDATE, 'YYYYMMDD')
WHERE base.ENV = 'PROD'
GROUP BY base.ENV, base.ENDDATE, T1.TOTAL, U1.TOTAL, X1.TOTAL
ORDER BY base.ENDDATE DESC;
非常感谢任何帮助。
谢谢
答案 0 :(得分:1)
我认为这就是你所需要的:
with t (dat, env, service, responses) as (
select to_date('15-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'T1', '4793' from dual union all
select to_date('15-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'U1', '3245' from dual union all
select to_date('15-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'X1', '4984' from dual union all
select to_date('14-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'T1', '5812' from dual union all
select to_date('14-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'U1', '3918' from dual union all
select to_date('14-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'X1', '3282' from dual union all
select to_date('13-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'T1', '11231' from dual union all
select to_date('13-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'U1', '1564' from dual union all
select to_date('13-NOV-2016', 'dd-mon-yyyy'), 'PROD', 'X1', '2816' from dual)
select tt.*, (total / lag(total, 1, null) over (order by dat) - 1) * 100 variance
from (select to_char(dat, 'yyyymmdd') dat, t1, x1, u1, t1 + x1 + u1 total
from t
pivot (sum(responses) for service in ('T1' t1, 'X1' x1, 'U1' u1))
) tt;
这里:with t
构造 - 源数据,然后是内部查询 - pivot为不同服务放入一行数据,然后在外部查询函数lag
中计算前一行值。有关详细信息,请参阅lag function和pivot query上的文档。
<强>更新强>
lag
的工作原理:lag
获取前一行的值。第一个参数是具有要采用的数据的列的名称,第二个 - 从当前行开始计数(前一个采用前一个,前一个采用2 - 2行,等等),第三个参数 - 如果没有前一行,则为默认值。行的顺序由order子句(上面的order by dat
)定义。要更改数据移位的方向,请更改使用函数lead
的排序顺序(asc / desc),该函数返回下一行的值(几乎与lag
相同)。