【问题标题】:My NULL record isn't showing up despite adding a WHERE IS NULL clause尽管添加了 WHERE IS NULL 子句,但我的 NULL 记录没有显示
【发布时间】:2020-02-10 14:00:44
【问题描述】:

我有一个看起来有点像这样的数据库:

表 1:------- 表 2:

ID1|Item Name        ID2|Date
---|----------       ---|---------
1  |A                1  |01/01/2020
2  |B                1  |11/01/2020
3  |C                1  |21/01/2020
                     2  |01/01/2020

我想要的是获取每个项目的最新日期,即使它没有:

Item Name|Latest Date
---------|-----------
A        |21/01/2020
B        |01/01/2020
C        |NULL

所以我这样做了:

SELECT [Item Name], [Date] AS [Latest Date]
FROM [Table 1]
LEFT JOIN [Table 2] AS A
ON [ID1] = [ID2]
WHERE [Date] IN
(
    SELECT MAX([Date]) FROM [Table 2] AS B
    WHERE A.[ID2] = B.[ID2]
)
OR [Date] IS NULL

但我得到的是这样的:

Item Name|Latest Date
---------|-----------
A        |21/01/2020
B        |01/01/2020

我做错了什么?如何让 C 出现?

我知道 WHERE 子句去掉了它,但是由于我添加了 IS NULL 检查,它不应该也出现吗?

【问题讨论】:

  • 不能reproduce。我得到了你所期望的。
  • 您应该会看到 C 的记录以及该 SQL 和数据。确保您的 SQL 与您发布的完全一样。
  • 也无法reproduce。意识到我的是 MySQL,但原理是一样的(SQLite fiddle 也给出了相同的结果)
  • 您已经提出了同样有效的问题并标记了答案 - 这只是“每组第一”概念的一个折痕。您有在没有 row_number 的情况下执行此操作的聚合建议 - 但我认为您可能过度简化了查询,而这些建议不足以实现您的目标。
  • @SMor 另一个问题现在结束了,这是一个完全不同的问题。

标签: sql-server database tsql


【解决方案1】:

所以我找到了原因,我一定是个笨蛋。

我有另一个 JOIN 子句,但我在没有它的情况下测试了我的查询,但得到了不需要的结果。所以我把它排除在外。看到多个用户无法复现后,我再次尝试不使用其他加入,得到了满意的结果。我的猜测是我在测试时忘记了 WHERE [Date] IS NULL 子句。

基本上,我现在拥有了我想要的东西

无论如何,非常感谢!

【讨论】:

    【解决方案2】:

    您可以使用以下内容:

    SELECT A.[Item Name], MAX(B.[Date]) AS [Latest Date]
    FROM [Table 1] AS A LEFT JOIN [Table 2] AS B ON A.[ID1] = B.[ID2]
    GROUP BY A.[Item Name]
    ORDER BY A.[Item Name] ASC
    

    您不必检查WHERE 子句中的日期。您可以LEFT JOIN 两个表和GROUP BY 项目名称。使用MAX,您可以获得每个组的最后日期。

    【讨论】:

    【解决方案3】:

    我认为您首先需要获取每个 ID 的最大日期,然后将其加入项目:

    SELECT T1.[Item Name], T2.[Date] AS [Latest Date]
    FROM [Table 1] AS T1
        LEFT JOIN (
            SELECT ID2, MAX(Date) AS [Date]
            FROM [Table 2] AS T2
            GROUP BY ID2
        ) AS T2 ON T1.ID1 = T2.ID2
    

    【讨论】:

      【解决方案4】:

      我会使用分析函数来获取最新值,如下所示:

      WITH Resultset
      AS
      (SELECT
              [Item Name]
             ,[DATE]
             ,ROW_NUMBER() OVER (PARTITION BY ID1 ORDER BY [Date] DESC) rn
          FROM [Table 1]
          LEFT JOIN [Table 2] AS A
              ON [ID1] = [ID2])
      SELECT
          [Item Name]
         ,[DATE]
      FROM Resultset
      WHERE rn = 1
      

      在这里,您按 [Date] 列排序,并始终获取 lates 行,如果它存在于表 2 中。

      如果table2的列比较多,很容易得到lates值,按日期

      【讨论】:

        【解决方案5】:

        还有另一种方法,您可以在其中声明一个变量并分配最大日期值。加入时,将日期设置为空值,如下所示。

        Create table Table1 (Id int, [Item Name] varchar(20))
        Insert into Table1 Values (1, 'A'), (2, 'B'), (3, 'C')
        
        Create table Table2 (Id2 int, dtDate Date)
        Insert into Table2 Values 
                (1, '01/01/2020'), (1, '01/11/2020'), (1, '01/21/2020'), (2, '01/01/2020')
        
        declare @maxDtDate date
        Select @maxDtDate = max(dtDate) from Table2
        
        SELECT 
               A.[Item Name], 
               MAX(Isnull(B.[dtDate], @maxDtDate)) AS [Latest Date]
        FROM [Table1] AS A LEFT JOIN [Table2] AS B ON A.[ID] = B.[ID2]
        Group By A.[Item Name]
        

        Live Demo

        【讨论】:

          猜你喜欢
          • 2016-10-07
          • 1970-01-01
          • 2011-11-17
          • 1970-01-01
          • 2010-10-23
          • 1970-01-01
          • 2011-09-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多