我正在尝试计算Oracle SQL中的10期移动平均值,但似乎无法正确使用它。
我的查询如下:
SELECT
BSM_ID
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-10/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD1"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-9/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD2"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-8/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD3"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-7/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD4"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-6/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD5"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-5/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD6"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-4/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD7"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-3/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD8"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-2/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD9"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-1/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD10"
,AVG(
CASE
WHEN D_DTM BETWEEN (SELECT MAX(D_DTM)-1/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI) AND (SELECT MAX(D_DTM)-10/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END
) AS "10 PERIOD AVG"
FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI
where D_DTM >= (SELECT MAX(D_DTM)-10/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
GROUP BY
BSM_ID
order by BSM_ID desc
但是继续得到“不是单组组功能”错误。我要做的是按列显示10个周期中的每个周期的%,然后将第11列作为AVG。我记得在SQL中做了类似的事情,但我无法在PLSQL
中找到合成器在SQL Server中我能够做到这一点来实现相同的结果:
SELECT carrier,
dIVISION,
LOcATION,
servicetype
,max(@maxwk-1) as ops_week_id
,max(case when ops_week_id = @maxwk-2 then (OT * 100.00) / ts else null end)
as [%_wk_1 ]
,max(case when ops_week_id = @maxwk-3 then (OT * 100.00) / ts else null end)
as [%_wk_2 ]
,max(case when ops_week_id = @maxwk-4 then (OT * 100.00) / ts else null end)
as [%_wk_3 ]
,max(case when ops_week_id = @maxwk-5 then (OT * 100.00) / ts else null end)
as [%_wk_4 ]
,avg(case when ops_week_id Between @maxwk-5 and @maxwk - 2 then (OT * 100.00) / ts else null end)
as [4_wk_SMA]
,avg(case when ops_week_id Between @maxwk-5 and @maxwk - 2 then (OT * 100.00) / ts else null end)
- 0.15 as [LwrBand]
,avg(case when ops_week_id Between @maxwk-5 and @maxwk - 2 then (OT * 100.00) / ts else null end)
+ 0.15 as [UprBand]
,max(case when ops_week_id = @maxwk-1 then (OT * 100.00) / ts else null end)
as [Ops_wk_id_av]
FROM la
GROUP BY la.DIVISION,la.LOCATION,la.servicetype,la.carrier
原始表结构如下:
D_DTM (datetime)
F_ID
REG_DTM
MRKT_ID
MRKT_NM
CL_ID
CL_NM
BSM_ID
BSM_NM
BSC_SEQ_ID
CSCD_ID
CSCD_NM
BTS_ID
V_ATT_CNT (denominator)
V_MBL_ORG_CNT
V_MBL_TER_CNT
V_SILENT_RETRY_CNT
V_CUST_BLK_CNT (numerator)
我想要做的是在最近10个小时内取百分比(V_CUST_BLK_CNT / V_ATT_CNT),然后按BSM_ID平均。因此生成的查询具有这样的结构
BSM_ID | PERIOD1%| PERIOD2%| PERIOD3%|等... | AVG%
我觉得我应该能够使用case whens来做到这一点,但似乎无法让小组和语法工作......
答案 0 :(得分:0)
您收到错误是因为您按bsm_id
进行分组,但引用了许多其他没有聚合函数的列。
如果您使用的是Oracle,请使用内置函数进行移动平均。这些是具有range
关键字的分析函数,类似于:
select bsm.*,
(sum(V_CUST_BLK_CNT) over (partition by bsm_id order by d_dtm range between 10 preceding and current row) /
(sum(V_CUST_ATT_CNT) over (partition by bsm_id order by d_dtm range between 10 preceding and current row))
from bsm
答案 1 :(得分:0)
好的,所以我的查询工作方式如下:
SELECT
BSM_ID
,MAX(PERIOD1) AS "PERIOD1"
,MAX(PERIOD2) AS "PERIOD2"
,MAX(PERIOD3) AS "PERIOD3"
,MAX(PERIOD4) AS "PERIOD4"
,MAX(PERIOD5) AS "PERIOD5"
,MAX(PERIOD6) AS "PERIOD6"
,MAX(PERIOD7) AS "PERIOD7"
,MAX(PERIOD8) AS "PERIOD8"
,MAX(PERIOD9) AS "PERIOD9"
,MAX(PERIOD10) AS "PERIOD10"
,(MAX(PERIOD1)+MAX(PERIOD2)+MAX(PERIOD3)+MAX(PERIOD4)+MAX(PERIOD5)+MAX(PERIOD6)+MAX(PERIOD7)+MAX(PERIOD8)+MAX(PERIOD9)+MAX(PERIOD10))/10 AS "AVG"
FROM
(
SELECT
BSM_ID
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-10/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD1"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-9/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD2"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-8/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD3"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-7/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD4"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-6/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD5"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-5/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD6"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-4/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD7"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-3/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD8"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-2/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD9"
,CASE
WHEN D_DTM = (SELECT MAX(D_DTM)-1/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
THEN (CASE WHEN sum(V_ATT_CNT) = 0 THEN NULL ELSE sum(V_CUST_BLK_CNT)/sum(V_ATT_CNT) END)
END AS "PERIOD10"
FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI
WHERE D_DTM >=(SELECT MAX(D_DTM)-10/24 FROM DMSN.DS3R_FH_1XRTT_BTS_LVL_KPI)
GROUP BY BSM_ID, D_DTM
)
GROUP BY
BSM_ID
我确信有一种更有效的方法可以做到这一点,但这很有效。