问题获取日期之间的总运行百分比差异

时间:2016-11-15 20:55:35

标签: plsql oracle10g

我遇到了一个查询问题,它会依次变成多个视图和一个完整的过程 生成一个表来显示从一天到下一天的差异。 说实话,在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;

非常感谢任何帮助。

谢谢

1 个答案:

答案 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 functionpivot query上的文档。

<强>更新
lag的工作原理:lag获取前一行的值。第一个参数是具有要采用的数据的列的名称,第二个 - 从当前行开始计数(前一个采用前一个,前一个采用2 - 2行,等等),第三个参数 - 如果没有前一行,则为默认值。行的顺序由order子句(上面的order by dat)定义。要更改数据移位的方向,请更改使用函数lead的排序顺序(asc / desc),该函数返回下一行的值(几乎与lag相同)。