【问题标题】:select the latest result based on DateTime field根据 DateTime 字段选择最新结果
【发布时间】:2014-05-23 23:34:41
【问题描述】:

我有一个只有 4 个字段的简单表格。

http://sqlfiddle.com/#!3/06d7d/1

CREATE TABLE Assessment (
  id INTEGER IDENTITY(1,1) PRIMARY KEY,
  personId INTEGER NOT NULL,
  dateTaken DATETIME,
  outcomeLevel VARCHAR(2)
)

INSERT INTO Assessment (personId, dateTaken, outcomeLevel)
VALUES (1, '2014-04-01', 'L1')

INSERT INTO Assessment (personId, dateTaken, outcomeLevel)
VALUES (1, '2014-04-05', 'L2')

INSERT INTO Assessment (personId, dateTaken, outcomeLevel)
VALUES (2, '2014-04-03', 'E3')

INSERT INTO Assessment (personId, dateTaken, outcomeLevel)
VALUES (2, '2014-04-07', 'L1')

我正在尝试根据 dateTaken 为每个“personId”选择他们的最新评估结果。

所以我想要的以下数据的输出是。

[personId, outcomeLevel]
[1, L2]
[2, L1]

谢谢, 丹尼

【问题讨论】:

    标签: sql sql-server-2008


    【解决方案1】:

    这是使用公用表表达式的可能解决方案:

    WITH cte AS (
    SELECT
        ROW_NUMBER() OVER (PARTITION BY personId ORDER BY dateTaken DESC) AS rn
        , personId
        , outcomeLevel
    FROM
        [dbo].[Assessment]
    )
    SELECT
        personId
        , outcomeLevel
    FROM
        cte
    WHERE
        rn = 1
    

    关于 CTE

    可以将公用表表达式 (CTE) 视为在单个 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集。 CTE 类似于派生表,因为它不存储为对象,并且仅在查询期间持续存在。与派生表不同,CTE 可以是自引用的,并且可以在同一查询中多次引用。 From MSDN: Using Common Table Expressions

    【讨论】:

      【解决方案2】:
      SELECT asst.personId,
             asst.outcomeLevel 
      FROM dbo.Assessment asst
      WHERE  asst.dateTaken=(SELECT MAX(ast.dateTaken) 
                             FROM assessment ast
                             WHERE asst.personid=ast.personId)
      ORDER BY asst.personId
      

      结果会是这样的

      personId 结果级别 1 L2 2 L1

      【讨论】:

        【解决方案3】:

        如果没有 cte,这应该可以完美地工作:

        SELECT [Table4].[personId], [Table4].[outcomeLevel]
        FROM (
            SELECT [Table1].[personId]
            FROM [Assessment] AS [Table1]
            GROUP BY [Table1].[personId]
            ) AS [Table2]
        CROSS APPLY (
            SELECT TOP (1) [Table3].[personId], [Table3].[outcomeLevel], [Table3].[dateTaken]
            FROM [Assessment] AS [Table3]
            WHERE [Table2].[personId] = [Table3].[personId]
            ORDER BY [Table3].[dateTaken] DESC
            ) AS [Table4]
        ORDER BY [Table4].[dateTaken] DESC
        

        【讨论】:

          【解决方案4】:
          ;with Cte as (Select personId,outcomeLevel, C= ROW_NUMBER()
                      over(PARTITION By personId Order By dateTaken desc)
                      From #Assessment
                      )
          
          Select * from cte where C=1
          

          示例here

          【讨论】:

            【解决方案5】:

            试试这个:

            SELECT a.personId, a.outcomeLevel
            FROM Assessment a
            INNER JOIN 
              (
                SELECT max(dateTaken) as datetaken1, personId 
                FROM Assessment
                GROUP BY personId ) b 
            ON a.dateTaken = b.datetaken1
            

            演示:http://sqlfiddle.com/#!3/06d7d/9

            想法是首先导出一个包含每个人的最大日期的表格,然后将其与日期字段上的原始表格连接起来,这样您就可以获得这个最大日期的结果级别...

            【讨论】:

              【解决方案6】:

              试试这个:

              ;with cte as
              (select personId pid, max(dateTaken) maxdate
               from assessment
               group by personId)
              
              select personId, outcomeLevel
              from assessment a
              inner join cte c on a.personId = c.pid
              where c.maxdate = a.dateTaken
              order by a.personId
              

              【讨论】:

              • 我能问一下吗?一开始是为了?只是为了确保它之前终止任何东西?
              • 基本上在脚本中划分WITH属于哪个。你可以参考这个以获得很好的解释:stackoverflow.com/questions/6938060/…。终止也是,因为分号用于此目的。
              • 你不能在另一个查询的左连接中使用它吗?关键字“WITH”附近的语法不正确。
              • 取决于你是怎么写的。 CTE 范围仅限于定义后立即进行的查询。
              • 我只是试图在 ASS.personId = P.personId 上包装一个 LEFT JOIN(你的答案)ASS.personId
              猜你喜欢
              • 1970-01-01
              • 2014-02-01
              • 1970-01-01
              • 2015-08-12
              • 2014-09-12
              • 1970-01-01
              • 2015-05-19
              • 1970-01-01
              • 2017-11-24
              相关资源
              最近更新 更多