【问题标题】:SQL Return every row even if Null valuesSQL 返回每一行,即使是 Null 值
【发布时间】:2017-10-01 01:02:27
【问题描述】:

我想返回 Contracts 表中的所有行,但第二个 WHERE 子句只产生不为空的行。 (换句话说,在“CAD”限制下方的代码中,大约有一半可能的行没有以加元交易的价值,因此不会返回——而我希望返回的所有可能行在适用的情况下显示 NULL 值)。

我认为这是一个左自连接,但我在语法上苦苦挣扎(和/或我是否需要做一个内部选择),

 SELECT MeasurableID,
     EntityID,
     MIN (ContractPrice) AS LowPrice,
     MAX (ContractPrice) AS HighPrice

 FROM dbo.Contracts

 WHERE dbo.Contracts.MeasurableID = 2018
  AND  Contracts.CurrencyCode IN ( 'CAD' ) 

 GROUP BY
  dbo.Contracts.MeasurableID,
  dbo.Contracts.EntityID  

【问题讨论】:

  • WHERE dbo.Contracts.MeasurableID = 2018 AND (Contracts.CurrencyCode IN ( 'CAD' ) OR Contracts.CurrencyCode IS NULL)
  • 在 where 子句中添加或使用 'null',目前它只检查 IN ('CAD')
  • Contracts.CurrencyCode 永远不会为 NULL(即其他合约以美元或印度卢比等为单位),因此这无济于事。
  • 请编辑澄清您的问题,而不是 cmets。此外,如果您还有其他问题,请将其作为问题发布,而不是在评论中。另外,你真的没有清楚地解释你想要什么,请编辑清楚。 (例如,您的第一句话的“但是”是对规范的改进还是查询有问题?)此外,这不是自联接或左联接,它没有联接。

标签: sql sql-server left-join self-join


【解决方案1】:

使用条件聚合:

SELECT  
  MeasurableID,
  EntityID,
  MIN (CASE WHEN CurrencyCode = 'CAD' THEN ContractPrice END) AS LowPrice,
  MAX (CASE WHEN CurrencyCode = 'CAD' THEN ContractPrice END) AS HighPrice
FROM dbo.Contracts
WHERE MeasurableID = 2018
GROUP BY MeasurableID, EntityID
ORDER BY MeasurableID, EntityID;

【讨论】:

  • 太棒了,这非常适合解决发布的问题。我需要阅读条件聚合,因为实际情况有三个额外的 WHERE 子句。
  • 没有太多可阅读的内容。通过CASE WHEN,我决定何时考虑 ContractPrice。如果您发现它更具可读性,可以添加 ELSE NULL。 MIN 和 MAX 忽略空值。就是这样。
  • 是的,但在此之前,我实际上想传递给 UserDefinedTable 中一组 CurrencyCodes 上方的查询。但是,以下是抛出错误“无法对包含聚合或子查询的表达式执行聚合函数”。 MIN (CASE WHEN dbo.Contracts.CurrencyCode IN (SELECT CurrencyCode from @TempTable4params) THEN ContractPrice END) AS LowPrice,
  • 啊,SQL Server 中令人讨厌的限制之一。然后分两步执行此操作: 1) 编写不带聚合的查询。 2) 编写一个主查询,您可以从该查询中选择并聚合。
【解决方案2】:

对于未来的读者,Thorsten 回答了所发布的问题,但在他的答案下方,无法付诸实践。因此,我不得不这样编码:

    SELECT
        t1.MeasurableID,
        t1.EntityID,
        t2.HIGH,
        t2.LOW
    FROM
        (
            SELECT
                MeasurableID,
                EntityID
            FROM
                Contracts
            WHERE
                MeasurableID IN (2017, 2018)
            GROUP BY
                MeasurableID,
                EntityID
        ) t1
    LEFT JOIN (
        SELECT
            MeasurableID,
            EntityID,
            MAX (ContractPrice) AS HIGH,
            MIN (ContractPrice) AS LOW
        FROM
            Contracts
        WHERE
            MeasurableID IN (2017, 2018)
        AND CurrencyCode IN ('CAD', 'BTC')
        GROUP BY
            MeasurableID,
            EntityID
    ) t2 ON t1.MeasurableID = t2.MeasurableID
    AND t1.EntityID = t2.EntityID
    ORDER BY
        t1.MeasurableID,
        t1.EntityID;

【讨论】:

    【解决方案3】:

    使用分组...

    按 CompanyID 从 Adjusters 组中选择 *;

    【讨论】:

      猜你喜欢
      • 2015-12-30
      • 2013-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 2019-05-28
      相关资源
      最近更新 更多