如果没有记录计数,则显示零 - ORACLE SQL 查询

Posted

技术标签:

【中文标题】如果没有记录计数,则显示零 - ORACLE SQL 查询【英文标题】:Show Zero if there is no record count - ORACLE SQL query 【发布时间】:2019-10-06 11:36:42 【问题描述】:

下面的 Oracle 查询给出了 error_messageSerial_num 是否存在任何不同的错误。

如果有零或无Different error 计数而不是显示空白/空结果。我怎样才能看到这样的输出?我尝试使用NVL(error_message,0)COALESCE (Sum(total),0),但没有得到想要的输出。

预期输出

1   Different Errors:       0

Oracle SQL 查询:

SELECT 
  1 as Index_Num, 
  CONCAT('Different Errors:  ', error_message || '# ' || serial_num), 
  SUM(total) 
FROM ( 
  SELECT error_message, serial_num, COUNT(*) total 
  FROM Table1 
  WHERE error_message NOT LIKE '%INVALID%' 
  GROUP BY error_message, serial_num
) 
GROUP BY error_message, serial_num

【问题讨论】:

您是在检查NULL 值还是error_message 实际上包含文本NULL?要检查 NULL 值,请使用 IS NULLIS NOT NULL 更新了 WHERE 子句 你看到了什么输出? 您的内部查询将按序列号为您提供不同错误消息的计数。由于您的外部查询使用相同的列执行GROUP BY,因此除了使用CONCAT 创建新列之外,它实际上并没有做任何事情。 是的。通常,如果有适当的错误,则计数显示1. Different Errors: Some error occurred for mismatch serials # 343543532 1 【参考方案1】:

为子查询创建一个CTE 并使用UNION ALLNOT EXISTS 来覆盖CTE 不返回任何行的情况:

WITH cte AS (
  SELECT error_message, serial_num, COUNT(*) total 
  FROM Table1 
  WHERE error_message NOT LIKE '%INVALID%' 
  GROUP BY error_message, serial_num
)
SELECT 
  1 as Index_Num, 
  CONCAT(
    'Different Errors:  ', 
    list_agg(error_message || '# ' || serial_num) within group (order by error_message)
  ), 
  SUM(total) 
FROM cte
UNION ALL
SELECT 1, 'Different Errors:  ', 0
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM cte)

【讨论】:

错误:ORA-00937:不是单组群函数 我假设您的代码适用于子查询返回行的情况,您只需要帮助它不返回任何行的情况。还是不行? 正确。一般来说,如果有适当的错误,那么结果是1. Different Errors: Some error occurred for mismatch serials # 343543532 1。这里的error_message是Some error occurred for mismatch serials,Serial_num是343543532,最后一个值1是总和/计数 因此,如果您的代码有效,那么将 UNION ALL 添加到其中也应该有效。我改为 list_agg() 以防子查询返回超过 1 行。 似乎 SUM(total) 必须更改为 NVL(SUM(total),0) 或 COALESCE (SUM(total),0)。否则,SUM 显示不带 0 的 BLANK 值。【参考方案2】:

天啊!看来我花的时间太长了。这是后代的另一种选择:

SELECT 
  1, 
  CONCAT(
    'Different Errors:  ', 
    CASE 
      WHEN src.error_message IS NULL THEN '' 
      ELSE src.error_message || ' # ' || src.serial_num 
    END
  ) Summary,
  COALESCE(src.total, 0) AS total
FROM dual -- Get a seed row (in case there are no rows in error table)
LEFT JOIN (
  SELECT error_message, serial_num, COUNT(*) total 
  FROM Table1 
  WHERE error_message NOT LIKE '%INVALID%' 
  GROUP BY error_message, serial_num
) src ON 0=0

SQL Fiddle

【讨论】:

非常感谢@ravioli,我发现您的代码对我的工作很有用。赞成:) 很高兴它有帮助:)【参考方案3】:

这并不完全符合您的要求,但可能会很有用。您可以使用grouping sets 轻松添加包含错误总数的行:

SELECT 1 as Index_Num, 
       ('Different Errors:  ' || error_message || '# ' || serial_num), 
       COUNT(*) as total 
FROM Table1 
WHERE error_message NOT LIKE '%INVALID%' 
GROUP BY GROUPING SETS ( (error_message, serial_num), () );

唉,即使有错误,这也会生成摘要行。我突然想到你可能会觉得这很有用。

【讨论】:

以上是关于如果没有记录计数,则显示零 - ORACLE SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 查询:如何将返回的记录限制为计数 > 1 但显示完整结果的记录?

检查数据框中的记录数是不是大于零而不使用计数火花

如果之前在组中没有看到值,则聚合值 - SQL / ORACLE

Full Outer Join 不包括双方的所有记录

查询返回语句 - PostgreSQL

Oracle中较长number型数值的科学计数显示问题