MAX Date子查询SQL Server

时间:2017-09-06 07:54:50

标签: sql sql-server group-by

我正在尝试在子查询中加入最大日期,但是我收到错误。我正在使用SQL服务器

SELECT Headcount.[Snapshot Date]
, Headcount.[ID]
, Assessment.[Assessment Date]
, Assessment.[Code]

FROM Headcount INNER JOIN Assessment ON Assessment.[ID] = Headcount.[ID]
WHERE Assessment.[Assessment Date] = 
                 (SELECT MAX(CAST(Assessment.[Assessment Date] as datetime)) 
                  FROM Assessmnet AS Z 
                  WHERE Z.[ID] = Assessment.[ID] 
                       AND Assessment.[Assessment Date] <= Headcount.[Snapshot Date]
                 )

但是我收到了一个错误:

  

聚合可能不会出现在WHERE子句中,除非它位于HAVING子句或选择列表中包含的子查询中,并且要聚合的列是外部引用。

3 个答案:

答案 0 :(得分:0)

您忘记了在子查询中指定的别名Z。如果您在子查询中使用Assessment,那么他会考虑外部查询中的Assessment,因为Assessment在子查询中的名称为Z

SELECT Headcount.[Snapshot Date]
, Headcount.[ID]
, Assessment.[Assessment Date]
, Assessment.[Code]

FROM Headcount INNER JOIN Assessment ON Assessment.[ID] = Headcount.[ID]
WHERE Assessment.[Assessment Date] = 
                 (SELECT MAX(CAST(Z.[Assessment Date] as datetime)) 
                  FROM Assessment AS Z 
                  WHERE Z.[ID] = Assessment.[ID] 
                       AND Z.[Assessment Date] <= Headcount.[Snapshot Date]
                 )

答案 1 :(得分:0)

问题出在where条件的子查询中,尝试这样的事情:

SELECT
    Headcount.[Snapshot Date],
    Headcount.[ID],
    Assessment.[Assessment Date],
    Assessment.[Code]
FROM Headcount
INNER JOIN Assessment ON Assessment.[ID] = Headcount.[ID]
WHERE Assessment.[Assessment Date] =
(
    SELECT
        MAX(CAST(Assessment.[Assessment Date] AS DATETIME))
    FROM Assessmnet AS Z
    GROUP BY
        Z.ID
    HAVING Z.[ID] = Assessment.[ID]
           AND Assessment.[Assessment Date] <= Headcount.[Snapshot Date]
);

答案 2 :(得分:0)

您应该写MAX(CAST(Z.[Assessment Date] as datetime))而不是MAX(CAST(Assessment.[Assessment Date] as datetime))。否则,您将在错误的表格中聚合。

以下查询可能有效(未经测试!):

SELECT Headcount.[Snapshot Date]
, Headcount.[ID]
, Assessment.[Assessment Date]
, Assessment.[Code]
FROM Headcount
INNER JOIN Assessment ON Assessment.[ID] = Headcount.[ID]
WHERE Assessment.[Assessment Date] =
                 (SELECT MAX(CAST(Z.[Assessment Date] as datetime))
                  FROM Assessment AS Z
                  WHERE Z.[ID] = Assessment.[ID] 
                    AND Z.[Assessment Date] <= Headcount.[Snapshot Date])

您还可以重写它以使用ROW_NUMBER为每次评估选择最新的行:

SELECT [Snapshot Date], [ID], [Assessment Date], [Code]
FROM (SELECT [Snapshot Date], [ID], [Assessment Date], [Code],
        ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [Assessment Date] DESC) rn
      FROM Headcount JOIN Assessment USING ([ID])
      WHERE [Assessment Date] <= [Snapshot Date]) t
WHERE rn = 1