从选择tsql

时间:2018-03-23 10:08:52

标签: sql sql-server tsql select null

我有一个包含一个月数据的表

SELECT 
       CASE WHEN (m1.is_internal = 1 AND m2.is_internal = 1) THEN
            SUM(CAST([size] AS BIGINT)) END AS internal_volume,
       CASE WHEN (m1.is_internal = 0 AND m2.is_internal = 1) THEN
            SUM(CAST([size] AS BIGINT)) END AS external_volume_in
FROM 
       messagesgal msg
LEFT JOIN 
       messages_addresses m1
       ΟΝ msg.originator = m1.address
LEFT JOIN 
       messages_addresses m2
       ΟΝ msg.recipient = m2.address
WHERE 
       date >= 43179
GROUP BY 
       floor(date), m1.is_internal, m2.is_internal

此查询给出了以下结果:

query_result

我想在此选择中排除NULL值的外观。 为什么它给我NULL值以防我想只得到这些大整数以及如何实现这个?

3 个答案:

答案 0 :(得分:1)

尝试添加排除Null并使用Coalesce函数的过滤器:

SELECT 
       Coalesce(CASE WHEN (m1.is_internal = 1 AND m2.is_internal = 1) THEN
            SUM(CAST([size] AS BIGINT)) END, 0) AS internal_volume,
       Coalesce(CASE WHEN (m1.is_internal = 0 AND m2.is_internal = 1) THEN
            SUM(CAST([size] AS BIGINT)) END, 0) AS external_volume_in
FROM 
       messagesgal msg
LEFT JOIN 
       messages_addresses m1
       ΟΝ msg.originator = m1.address
LEFT JOIN 
       messages_addresses m2
       ΟΝ msg.recipient = m2.address
WHERE 
       date >= 43179 and internal_volume IS NOT NULL AND external_volume_in IS NOT NULL 
GROUP BY 
       floor(date), m1.is_internal, m2.is_internal

答案 1 :(得分:1)

您获得了NULL个值,因为您要对列表达式而不是WHERE上的总和进行过滤。这两个NULL记录都是is_internal不是1的记录,因此CASE都不会与WHEN匹配并返回默认值NULL,而不是计算SUM()

尝试过滤您的"而非内部"您WHERE上的记录如下:

--...
WHERE 
       date >= 43179 AND
       m2.is_internal = 1
GROUP BY 
       floor(date), m1.is_internal, m2.is_internal

然后,您可以从CASE中删除其他条件。另外,我发现SUM(CASE...)更容易阅读。

SUM(CASE WHEN m1.is_internal = 1 THEN CAST([size] AS BIGINT) END) AS internal_volume,
SUM(CASE WHEN m1.is_internal = 0 THEN CAST([size] AS BIGINT) END) AS external_volume_in

一般而言,如果您想根据列的值来过滤查询结果(如果它们是复杂的表达式,并且您不想在WHERE或者HAVING中重复它们;WITH Results AS ( SELECT CASE WHEN (m1.is_internal = 1 AND m2.is_internal = 1) THEN SUM(CAST([size] AS BIGINT)) END AS internal_volume, CASE WHEN (m1.is_internal = 0 AND m2.is_internal = 1) THEN SUM(CAST([size] AS BIGINT)) END AS external_volume_in FROM messagesgal msg LEFT JOIN messages_addresses m1 ΟΝ msg.originator = m1.address LEFT JOIN messages_addresses m2 ΟΝ msg.recipient = m2.address WHERE date >= 43179 GROUP BY floor(date), m1.is_internal, m2.is_internal ) SELECT R.* FROM Results AS R WHERE R.internal_volume IS NOT NULL OR R.external_volume_in IS NOT NULL ),您应该尝试将它们移动到子查询或CTE并在之后过滤:

{{1}}

答案 2 :(得分:0)

试试这个:

case when m2.is_internal = 1 then 
    case m1.is_internal when 1 then 'internal volume'
                        when 0 then 'external volume in'
    end
end [type],
case when m2.is_internal = 1 then 
    case m1.is_internal when 1 then SUM(CAST([size] AS BIGINT))
                        when 0 then SUM(CAST([size] AS BIGINT))
    end
end [value]

然后你可以将它包装在外部查询中,在那里你可以选择值[value] is not null