显示 case 表达式中的空白行

Posted

技术标签:

【中文标题】显示 case 表达式中的空白行【英文标题】:Display blank rows from a case expression 【发布时间】:2019-07-15 14:14:21 【问题描述】:

我正在编写一个 sql 报告,对我提出的要求之一是包含 CASE 表达式的两个选项的行。

该报告用于显示数据库中所有客户与 3 个选定客户中的每一个之间的“成本计算”和“非成本计算”交易的计数。

请查看所需的示例布局。

CUSTOMER_ID | CUSTOMER_NAME | COSTING     | CUST_1 | CUST_2 | CUST_3
12          | Red Corp      | Non-costing | 1245   | 734    | 84
12          | Red Corp      | Costing     | 376    | 23     | 2
17          | Blue Corp     | Non-costing | 4538   | 36     | 3256
17          | Blue Corp     | Costing     | 0      | 0      | 0
...

我已尝试将 COSTING 列放在 case 语句中。但是,由于它是空白的,因此我无法在输出中显示示例“Blue Corp”“成本核算”行。

select  CUSTOMER_ID
        ,CUSTOMER_NAME
        ,case 
            when PURCHASE_VALUE = 0 or PURCHASE_VALUE is null then 'Non-costing'
            when PURCHASE_VALUE != 0 or PURCHASE_VALUE is not null then 'Costing'
        end AS COSTING
,count(CASE WHEN CUSTOMER_ID = 11 then 1 ELSE NULL END) as "CUST_1"
,count(CASE WHEN CUSTOMER_ID = 22 then 1 ELSE NULL END) as "CUST_2"
,count(CASE WHEN CUSTOMER_ID = 33 then 1 ELSE NULL END) as "CUST_3"
from schema.CUSTOMER_TRANSACTIONS
group by case 
            when PURCHASE_VALUE = 0 or PURCHASE_VALUE is null then 'Non-costing'
            when PURCHASE_VALUE != 0 or PURCHASE_VALUE is not null then 'Costing'
        end 
        ,CUSTOMER_ID
        ,CUSTOMER_NAME

我目前得到的结果与示例相同,但缺少 0 计数行。 请在下面查看我目前得到的输出。

CUSTOMER_ID | CUSTOMER_NAME | COSTING     | CUST_1 | CUST_2 | CUST_3
12          | Red Corp      | Non-costing | 1245   | 734    | 84
12          | Red Corp      | Costing     | 376    | 23     | 2
17          | Blue Corp     | Non-costing | 4538   | 36     | 3256
...

【问题讨论】:

我无法理解您的问题?你能提供你期望的结果吗 我希望它看起来像顶部的示例表。 目前你得到了什么输出?你也可以发一下吗 这似乎是由于您的客户端应用程序的格式问题。你用什么来运行 SQL? Standin.Wolf 我已经更新了问题以包含我当前输出的清晰示例。 【参考方案1】:

使用cross join 生成行,使用left join 添加列:

select c.CUSTOMER_ID, c.CUSTOMER_NAME, t.costing,
       sum(CASE WHEN CUSTOMER_ID = 11 then 1 ELSE 0 END) as CUST_1,
       sum(CASE WHEN CUSTOMER_ID = 22 then 1 ELSE 0 END) as CUST_2,
       sum(CASE WHEN CUSTOMER_ID = 33 then 1 ELSE 0 END) as CUST_3
from (select distinct ct.customer_id, ct.customer_name
      from schema.CUSTOMER_TRANSACTIONS ct
     ) c cross join
     (select 'Non-costing' as costing from dual union all
      select 'Costing' from dual
     ) t left join
     schema.customer_transactions ct
     on c.customer_id = ct.customer_id,
        t.costing = (case when PURCHASE_VALUE = 0 or PURCHASE_VALUE is null
                         then 'Non-costing'
                         else 'Costing'
                     end)
group by c.CUSTOMER_ID, c.CUSTOMER_NAME, t.type;

【讨论】:

【参考方案2】:

根据您的评论,

Alex Poole,您是对的,没有“成本核算”数据 “蓝色公司”。但是我希望该行显示为 0 而不是 完全出现了。

我认为您需要生成其中一个costings不可用的记录。

我尝试创建查询,如果“成本核算”或“非成本核算”记录对任何客户均不可用,则该查询将生成记录。

我无法对其进行测试,所以如果您遇到任何问题,请分享。

-- Your original query starts from here
WITH DATAA AS (select  CUSTOMER_ID
        ,CUSTOMER_NAME
        ,case 
            when PURCHASE_VALUE = 0 or PURCHASE_VALUE is null then 'Non-costing'
            when PURCHASE_VALUE != 0 or PURCHASE_VALUE is not null then 'Costng'
        end AS COSTING
,count(CASE WHEN CUSTOMER_ID = 11 then 1 ELSE NULL END) as "CUST_1"
,count(CASE WHEN CUSTOMER_ID = 22 then 1 ELSE NULL END) as "CUST_2"
,count(CASE WHEN CUSTOMER_ID = 33 then 1 ELSE NULL END) as "CUST_3"
from schema.CUSTOMER_TRANSACTIONS
group by case 
            when PURCHASE_VALUE = 0 or PURCHASE_VALUE is null then 'Non-costing'
            when PURCHASE_VALUE != 0 or PURCHASE_VALUE is not null then 'Costing'
        end 
        ,CUSTOMER_ID
        ,CUSTOMER_NAME)
-- Your original query ends here


-- Solution
SELECT
    CUSTOMER_ID,
    CUSTOMER_NAME,
    COSTING,
    CUST_1,
    CUST_2,
    CUST_3
FROM
    DATAA
UNION ALL
( SELECT
    CUSTOMER_ID,
    CUSTOMER_NAME,
    CASE
        WHEN COUNT(CASE
            WHEN COSTING = 'Non-costing' THEN 1
        END) = 0 THEN 'Non-costing'
        WHEN COUNT(CASE
            WHEN COSTING = 'Costing' THEN 1
        END) = 0 THEN 'Costing'
    END AS COSTING,
    0,
    0,
    0
FROM
    DATAA D1
GROUP BY
    CUSTOMER_ID,
    CUSTOMER_NAME
HAVING ( COUNT(CASE
    WHEN COSTING = 'Non-costing' THEN 1
END) = 0
         OR COUNT(CASE
    WHEN COSTING = 'Costng' THEN 1
END) = 0 )
);

干杯!!

【讨论】:

这很完美,它完全解决了我的问题。谢谢。【参考方案3】:

你可以试试这个。如果没有,它会给你 0。

select  CUSTOMER_ID
        ,CUSTOMER_NAME
, CASE WHEN ISNULL(PURCHASE_Value,0) = 0 THEN 'Non-costing' ELSE 'Costing' END        
,SUM(CASE WHEN CUSTOMER_ID = 11 then 1 ELSE 0 END) as "CUST_1"
,SUM(CASE WHEN CUSTOMER_ID = 22 then 1 ELSE 0 END) as "CUST_2"
,SUM(CASE WHEN CUSTOMER_ID = 33 then 1 ELSE 0 END) as "CUST_3"
from schema.CUSTOMER_TRANSACTIONS
group by CUSTOMER_ID
        ,CUSTOMER_NAME
,PURCHASE_Value

【讨论】:

你不认为这会出错,因为PURCHASE_Value 直接用于SELECT 而不是GROUP BY

以上是关于显示 case 表达式中的空白行的主要内容,如果未能解决你的问题,请参考以下文章

java正则表达式,怎么匹配空白行

使用正则表达式删除任何空白行

linux查看文件内容命令

在 Emacs 中将连续的空白显示为点

openbabelGUI转换为空白

如何在给定表达式的情况下使文本框空白而不是隐藏?