【问题标题】:NULLS being excluded when filtering string literal过滤字符串文字时排除 NULLS
【发布时间】:2020-07-02 02:21:23
【问题描述】:

我有以下查询,我打算过滤/排除WHERE 范围类型或市场概念等于字符串文字“PLACEHOLDER”。由于反馈,我们发现我们实际上也排除了这些字段为NULL 的任何实例。这让我有些意外,有什么建议可以解释一下吗?

查询:

SELECT DISTINCT M.MATERIAL, 
       A.MARKET_CONCEPT, 
       A.RANGE_TYPE
FROM VW_MRP_ALLOCATION_COMBINED M
JOIN VW_ARTICLE_ATTRIBUTES_COMBINED A ON M.Material = A.Article AND M.SALES_ORGANIZATION = A.SALES_ORGANIZATION
WHERE M.stock_type = '' 
AND A.market_concept <> 'PLACEHOLDER'
AND A.RANGE_TYPE <> 'PLACEHOLDER' 
AND A.Article in ('BK0348',
'BQ2718',
'BQ2719',
'BS3674',
'CF3607',
'CF3608',
'CF3609',
'CF3610',
'CV5091',
'D94751',
'DH6911',
'DT5039')
AND M.Sales_Organization = 6040; 

【问题讨论】:

  • NULL 是没有值,它们不是空字符串。如果你想包含一个空值,你可以使用 {somevalue} IS NULL
  • 根据定义null 是一个未知值,因此不能相等或不相等。如果要包含空值,则需要特别包含它们,例如(A.market_concept &lt;&gt; 'PLACEHOLDER' OR A.market_concept is null)
  • 这敲响了一些钟声。如果我将条件更改为“喜欢”而不是直接等于或不等于会发生什么?这似乎仍然不起作用
  • 同样的交易......你可以做coalesce(A.market_concept,'') &lt;&gt; 'PLACEHOLDER',但它不会像我上面给出的解决方案那样好,因为你在比较之前对值使用了一个函数。
  • 同样的事情,NULL &lt;any-comparison-operator&gt; &lt;any-value&gt; 总是FALSE

标签: sql sql-server null


【解决方案1】:

使用“IS NULL”关键字绘制NULL记录以进行比较。这是一个如何获取空记录的示例

with data
  as (select 'PLACEHOLDER' as market_concept,'PLACEHOLDER' as range_type
      union all
      select 'MarketConcept1' as market_concept,'Rangetype1' as range_type
      union all
      select null as market_concept, null as range_type
      )
 select *
 from data
 where ((market_concept <> 'PLACEHOLDER'
         and range_type <>'PLACEHOLDER'
         )
      --This OR condition brings out the records which are null
      OR(market_concept is null
         and range_type is null
         )
       )

+----------------+------------+
| market_concept | range_type |
+----------------+------------+
| MarketConcept1 | Rangetype1 |
| null           | null       |
+----------------+------------+

【讨论】:

  • 那是假设两列都需要一起为空?如果只有一个为空怎么办?
  • 我假设基于查询操作共享。任一字段上的单个 Null 将是(market_concept 为 null 或 range_type 为 null)
【解决方案2】:

我建议明确:

(A.market_concept <> 'PLACEHOLDER' OR A.market_concept IS NULL) AND
(A.RANGE_TYPE <> 'PLACEHOLDER' A.range_type IS NULL) AND

注意:这里假设'PLACEHOLDER' 不是NULL。如果可能的话,我建议提出一个新问题,并提供清晰的样本数据和期望的结果。

【讨论】:

    【解决方案3】:

    您可以使用 ISNULL 函数将 NULL 值视为与占位符相同。

    SELECT DISTINCT M.MATERIAL, 
           A.MARKET_CONCEPT, 
           A.RANGE_TYPE
    FROM VW_MRP_ALLOCATION_COMBINED M
    JOIN VW_ARTICLE_ATTRIBUTES_COMBINED A ON M.Material = A.Article AND M.SALES_ORGANIZATION = A.SALES_ORGANIZATION
    WHERE M.stock_type = '' 
    AND ISNULL(A.market_concept,'PLACEHOLDER') <> 'PLACEHOLDER'
    AND ISNULL(A.RANGE_TYPE,'PLACEHOLDER') <> 'PLACEHOLDER' 
    AND A.Article in ('BK0348',
    'BQ2718',
    'BQ2719',
    'BS3674',
    'CF3607',
    'CF3608',
    'CF3609',
    'CF3610',
    'CV5091',
    'D94751',
    'DH6911',
    'DT5039')
    AND M.Sales_Organization = 6040; 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 2010-10-28
      • 1970-01-01
      • 2012-06-26
      • 2022-07-04
      • 2022-01-16
      相关资源
      最近更新 更多