在复杂 CASE 语句的结果中找不到时如何报告带有 0(零)的标签

How to report a label with 0(zero) when not found in the result in a complex CASE statement

出于报告目的,我需要创建一个乍一看非常简单的报告,只是创建它是一个挑战!需要更改标签的值,并且需要计算每个标签的出现次数。

我已经创建了一个看起来工作正常的查询,只是它在没有出现时不显示标签。

这是我现在使用的代码。

COLUMN c1 HEADING "Entity" FORMAT A8
COLUMN c2 HEADING "Quantity" FORMAT 9999999
BREAK ON c1
SELECT (CASE 
         WHEN cat_code = '1234'
          AND SUBSTR(prod_nbr,1,6) IN (SELECT SUBSTR(prod_code,1,6)
                                                FROM product_codes
                                              WHERE SUBSTR(prod_code,1,5) != 12345
                                                AND SUBSTR(prod_code,1,6) != 987654
                                             )  
          THEN 'AAA_X'
        WHEN cat_code != '1234'
         AND SUBSTR(prod_nbr,1,6) IN (SELECT SUBSTR(prod_code,1,6)
                                               FROM product_codes
                                             WHERE SUBSTR(prod_code,1,5) != 12345
                                               AND SUBSTR(prod_code,1,6) != 987654
                                            )   
          THEN 'AAA_Y'
        WHEN cat_code = '1234'
         AND SUBSTR(prod_nbr,1,6) NOT IN (SELECT SUBSTR(prod_code,1,6)
                                                   FROM product_codes
                                                 )  
             THEN 'BBB_X'
        WHEN cat_code != '1234'
         AND SUBSTR(prod_nbr,1,6) NOT IN (SELECT SUBSTR(prod_code,1,6)
                                                   FROM product_codes
                                                 )  
             THEN 'BBB_Y'
       END) c1
     , COUNT(*) c2
FROM purchases
WHERE end_time >= '&1'
  AND end_time <  '&2'
GROUP BY (CASE 
         WHEN cat_code = '1234'
          AND SUBSTR(prod_nbr,1,6) IN (SELECT SUBSTR(prod_code,1,6)
                                                FROM product_codes
                                              WHERE SUBSTR(prod_code,1,5) != 12345
                                                AND SUBSTR(prod_code,1,6) != 987654
                                             )  
          THEN 'AAA_X'
        WHEN cat_code != '1234'
         AND SUBSTR(prod_nbr,1,6) IN (SELECT SUBSTR(prod_code,1,6)
                                               FROM product_codes
                                             WHERE SUBSTR(prod_code,1,5) != 12345
                                               AND SUBSTR(prod_code,1,6) != 987654
                                            )   
          THEN 'AAA_Y'
        WHEN cat_code = '1234'
         AND SUBSTR(prod_nbr,1,6) NOT IN (SELECT SUBSTR(prod_code,1,6)
                                                   FROM product_codes
                                                 )  
             THEN 'BBB_X'
        WHEN cat_code != '1234'
         AND SUBSTR(prod_nbr,1,6) NOT IN (SELECT SUBSTR(prod_code,1,6)
                                                   FROM product_codes
                                                 )  
             THEN 'BBB_Y'
       END)
ORDER BY 1;

对于标签 BBB_X 和 BBB_Y,数据库中还没有数据,因此报告中没有显示。我正在寻找的结果就像这个例子。

Entity;Quantity
------ --------
AAA_X ;  123456
AAA_Y ;  654321
BBB_X ;       0
BBB_Y ;       0

AAA_X,AAA_Y,BBB_X,BBB_Y 值是从某些表达式派生的,在您的情况下这太恒定了。因此您可以通过将逻辑转移到聚合函数并使用 AAA_X,AAA_Y,BBB_X,BBB_Y 作为基础数据来实现所需的输出,如下所示:

WITH BASE_DATA AS (
SELECT REGEXP_SUBSTR(D,'[^,]+', 1, LEVEL) AS C1 FROM
    (SELECT 'AAA_X,AAA_Y,BBB_X,BBB_Y' D FROM DUAL)
CONNECT BY REGEXP_SUBSTR(D,'[^,]+', 1, LEVEL) IS NOT NULL
)
SELECT b.C1, SUM (CASE 
         WHEN b.C1 = 'AAA_X' AND cat_code = '1234'
          AND SUBSTR(prod_nbr,1,6) IN (SELECT SUBSTR(prod_code,1,6)
                                                FROM product_codes
                                              WHERE SUBSTR(prod_code,1,5) != 12345
                                                AND SUBSTR(prod_code,1,6) != 987654
                                             )  
          THEN 1
        WHEN b.C1 = 'AAA_Y' AND cat_code != '1234'
         AND SUBSTR(prod_nbr,1,6) IN (SELECT SUBSTR(prod_code,1,6)
                                               FROM product_codes
                                             WHERE SUBSTR(prod_code,1,5) != 12345
                                               AND SUBSTR(prod_code,1,6) != 987654
                                            )   
          THEN 1
        WHEN b.C1 = 'BBB_X' AND cat_code = '1234'
         AND SUBSTR(prod_nbr,1,6) NOT IN (SELECT SUBSTR(prod_code,1,6)
                                                   FROM product_codes
                                                 )  
             THEN 1
        WHEN b.C1 = 'BBB_Y' AND cat_code != '1234'
         AND SUBSTR(prod_nbr,1,6) NOT IN (SELECT SUBSTR(prod_code,1,6)
                                                   FROM product_codes
                                                 )  
             THEN 1
       END) c2
    -- , COUNT(*) c2
FROM BASE_DATA b LEFT JOIN purchases p ON (1 = 1)
WHERE end_time >= '&1'
  AND end_time <  '&2'
GROUP BY b.C1
ORDER BY 1;

干杯!!