【问题标题】:Exclude NULL values from selection tsql从选择 tsql 中排除 NULL 值
【发布时间】:2018-03-23 10:08:51
【问题描述】:

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

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

这个查询给了我以下结果:

我想在此选择中排除 NULL 值的出现。 如果我只想获得这些大整数,为什么它会给我 NULL 值以及如何实现这一点?

【问题讨论】:

  • 也许如果你在选择语句中添加date 你会得到答案
  • 请分享一些示例数据和预期输出
  • internal_volume IS NOT NULL AND external_volume_in IS NOT NULL 添加到您的WHERE 中?预期结果尚不清楚。
  • floor(date)?这是什么意思?

标签: sql sql-server tsql select null


【解决方案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

一般来说,如果您想按列的值过滤查询结果(如果它们是复杂的表达式并且您不想在WHEREHAVING 中重复它们),您应该尝试将它们移动到子查询或 CTE 并随后过滤:

;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

【讨论】:

    【解决方案2】:

    尝试添加一个排除 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
    

    【讨论】:

      【解决方案3】:

      试试这个:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-24
        • 2014-06-26
        • 2018-12-07
        • 1970-01-01
        相关资源
        最近更新 更多