下面是一个代码片段,我试图逐行计算所有四个 case 语句结果的平均值。如果省略 AVG 函数,报告将正确列出四个计算列作为四个数字。但是当按原样运行时,我收到“错误或丢失数据库接近“order_interval_using_pvs1_order_date”
有人可以告诉我如何根据要求计算平均值吗?非常感谢。
AVG(
CASE
WHEN LAG(order_entry_date,1) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC) <> ""
THEN JULIANDAY("orders_tbl"."order_entry_date") - JULIANDAY(LAG(order_entry_date,1) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC))
END "order_interval_using_pvs1_order_date",
CASE
WHEN LAG(order_entry_date,2) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC) <> ""
THEN JULIANDAY(LAG( order_entry_date, 1 ) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC)) - JULIANDAY(LAG(order_entry_date,2) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC))
END "order_interval_using_pvs2_order_date",
CASE
WHEN LAG(order_entry_date,3) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC) <> ""
THEN JULIANDAY(LAG( order_entry_date, 2 ) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC)) - JULIANDAY(LAG(order_entry_date,3) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC))
END "order_interval_using_pvs3_order_date",
CASE
WHEN LAG(order_entry_date,4) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC) <> ""
THEN JULIANDAY(LAG( order_entry_date, 3 ) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC)) - JULIANDAY(LAG(order_entry_date,4) OVER (PARTITION BY cust_id ORDER BY order_entry_date ASC))
END "order_interval_using_pvs4_order_date"
) AS "Avg_ordr_interval",
创建子查询获取同一行中的前几行值,以便您可以自己计算平均值。您可以使用 Coalesce() 函数(在子查询中)来处理空值。
样本数据如下:
样本数据:
/* c u s t o m e r s :
CUST_ID CUST_NAME
------- ----------
1 John
2 Jane
3 Mike */
/* o r d e r s :
ORD_ID ORD_DATE CUST_ID
------ ---------- -------
101 2023-07-15 1
102 2023-08-31 1
103 2023-11-11 1
131 2023-09-05 2
132 2023-11-17 2
151 2023-08-15 3
152 2023-09-08 3
153 2023-10-29 3
154 2023-11-30 3
155 2023-12-12 3 */
...使用 Case 表达式来获取天数和计数都存在的值(不是空值)。聚合和分组依据...
SQL:
Select CUST_ID, CUST_NAME,
Round( Sum( ( Case When DAY_DIFF_1 > 0 Then DAY_DIFF_1 Else 0 End +
Case When DAY_DIFF_2 > 0 Then DAY_DIFF_2 Else 0 End +
Case When DAY_DIFF_3 > 0 Then DAY_DIFF_3 Else 0 End +
Case When DAY_DIFF_4 > 0 Then DAY_DIFF_4 Else 0 End
)
) /
Sum( ( Case When DAY_DIFF_1 > 0 Then 1 Else 0 End +
Case When DAY_DIFF_2 > 0 Then 1 Else 0 End +
Case When DAY_DIFF_3 > 0 Then 1 Else 0 End +
Case When DAY_DIFF_4 > 0 Then 1 Else 0 End
)
)
, 2) "AVG_DAYS"
From ( Select c.CUST_ID, c.CUST_NAME,
o.ORD_DATE,
JULIANDAY(o.ORD_DATE) - JULIANDAY(COALESCE(LAG(o.ORD_DATE, 1) Over(Partition By c.CUST_ID Order By o.ORD_DATE), o.ORD_DATE)) "DAY_DIFF_1",
JULIANDAY(COALESCE(LAG(o.ORD_DATE, 1) Over(Partition By c.CUST_ID Order By o.ORD_DATE), o.ORD_DATE)) -
JULIANDAY(COALESCE(LAG(o.ORD_DATE, 2) Over(Partition By c.CUST_ID Order By o.ORD_DATE), o.ORD_DATE )) "DAY_DIFF_2",
JULIANDAY(COALESCE(LAG(o.ORD_DATE, 2) Over(Partition By c.CUST_ID Order By o.ORD_DATE), o.ORD_DATE)) -
JULIANDAY(COALESCE(LAG(o.ORD_DATE, 3) Over(Partition By c.CUST_ID Order By o.ORD_DATE), o.ORD_DATE )) "DAY_DIFF_3",
JULIANDAY(COALESCE(LAG(o.ORD_DATE, 3) Over(Partition By c.CUST_ID Order By o.ORD_DATE), o.ORD_DATE)) -
JULIANDAY(COALESCE(LAG(o.ORD_DATE, 4) Over(Partition By c.CUST_ID Order By o.ORD_DATE), o.ORD_DATE )) "DAY_DIFF_4"
From customers c
Inner Join orders o ON(o.CUST_ID = c.CUST_ID)
Order By c.CUST_ID
)
Group By CUST_ID, CUST_NAME
Order By CUST_ID, CUST_NAME
/* R e s u l t :
CUST_ID CUST_NAME DAYS CNT AVG_DAYS
------- --------- ------- --- ---------
1 John 166 3 55.33
2 Jane 73 1 73
3 Mike 325 10 32.5 */