【问题标题】:Oracle SQLPLUS AVG function when using a CASE statement使用 CASE 语句时的 Oracle SQLPLUS AVG 函数
【发布时间】:2018-12-11 16:23:33
【问题描述】:

对于 4 台服务器的性能报告,我想获得每个服务器每个周期的 AVG,在本例中为 1 分钟。我可以获得 COUNT 和 MAX,但不能获得每台服务器的 AVG(stay)。每台服务器都由 CREATE_APP_LOC_ID 列标识,其值为 0、1、2 或 3。我在查询中做错了什么?

感谢您的帮助。

输出如下所示:

                     Overall                                           server_1                server_2                server_3                server_4 
                                   Max     Avg                                  Max    Avg              Max    Avg              Max    Avg              Max    Avg
End Time             TXN   TPS    Stay    Stay   Appr   Decl Other       TXN   Stay   Stay       TXN   Stay   Stay       TXN   Stay   Stay       TXN   Stay   Stay
---------------- ------- ----- ------- ------- ------ ------ ----- --------- ------ ------ --------- ------ ------ --------- ------ ------ --------- ------ ------
2018-12-10 16:40    2354    39     513      74   1345   1008     1       599    316     11       559     48      7       599    513     29       597    328     28

这是使用的查询:

ACCEPT start_time CHAR PROMPT 'Enter start time (yyyy-mm-dd hh:mm): '
ACCEPT stop_time CHAR PROMPT 'Enter end time (yyyy-mm-dd hh:mm)  : '

DEFINE time_diff = 1

SELECT TO_CHAR((MIN(end_time)+(&time_diff/24)), 'YYYY-MM-DD HH24:MI') c1, COUNT(*) c2,
       COUNT(*)/60 c3,
       MAX(stay) c4, ROUND(AVG(stay)) c5,
       SUM (CASE WHEN SUBSTR(TXN.RES_CODE,1,3) = 'APP' THEN 1 ELSE 0 END) c10,
       SUM (CASE WHEN SUBSTR(TXN.RES_CODE,1,3) = 'DEC' THEN 1 ELSE 0 END) c11,
       SUM (CASE WHEN SUBSTR(RES_CODE,1,3) <> 'APP' AND SUBSTR(RES_CODE,1,3) <> 'DEC' THEN 1 ELSE 0 END) c12,
/*server_1*/
       SUM (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 0 THEN 1 ELSE 0 END) c13,
       MAX (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 0 THEN stay ELSE 0 END) c20,
       AVG (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 0 THEN stay ELSE 0 END) c21, 
/*server_2*/
       SUM (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 1 THEN 1 ELSE 0 END) c14,
       MAX (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 1 THEN stay ELSE 0 END) c20,
       AVG (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 1 THEN stay ELSE 0 END) c21,
/*server_3*/
       SUM (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 2 THEN 1 ELSE 0 END) c15,
       MAX (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 2 THEN stay ELSE 0 END) c20,
       AVG (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 2 THEN stay ELSE 0 END) c21, 
/*server_4*/
       SUM (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 3 THEN 1 ELSE 0 END) c16,
       MAX (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 3 THEN stay ELSE 0 END) c20
       AVG (CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) = 3 THEN stay ELSE 0 END) c21  
FROM txn
WHERE txn_origin_id NOT IN (2,3)
  AND end_time >= '&start_time'
  AND end_time  < '&stop_time'
GROUP BY TO_CHAR(end_time, 'YYYY-MM-DD HH24:MI')
ORDER BY 1;

【问题讨论】:

  • “无法获得平均值”是什么意思?当你尝试时会发生什么?语法错误?运行时错误?没有抛出错误,但结果是错误的?还有什么?
  • stay的数据类型是什么?并且留下包含NULLS吗?
  • 无论如何:ELSE 0 表达式的 CASE 部分可能是问题所在;它不会影响SUMMAX(也许),但它肯定会影响COUNT,即使您似乎不这么认为。省略ELSE 0(然后默认值ELSE NULL,这是正确的)。
  • @mathguy,每台服务器每分钟的 AVG 结果在此脚本中与我进行一次仅从一台服务器选择数据的查询时不同。 MAX 和 SUM 的数据是正确的
  • @vivek STAY 的数据类型不是 NULL NUMBER(9)。

标签: sql oracle average


【解决方案1】:

根据我的假设,由于ELSE 0 部分,您得到了错误的 AVG。 尝试使用:

ROUND(AVG((CASE WHEN SUBSTR(CREATE_APP_LOC_ID, 1, 1) in (0,1,2,3) THEN stay ELSE 0 END))) c5,

而不是

ROUND(AVG(stay)) c5,

【讨论】:

  • 根据你的假设?我在原始帖子下方的 cmets 中看到了这一点,但我没有看到 指出这一点。真丢脸。
猜你喜欢
  • 2023-02-07
  • 1970-01-01
  • 2011-09-15
  • 2012-10-03
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多