【问题标题】:How to filter rows on Max date and Max Id如何过滤 Max date 和 Max Id 上的行
【发布时间】:2016-11-17 14:57:50
【问题描述】:

这是我的 SQL 表

RecordID      RecordState     Time
-----------------------------------
record1       failed          1:00
record1       passed          2:00

record2       passed          2:15

record3       failed          3:00

record4       passed          4:00
record4       failed          5:00

我只需要选择“失败”的记录。

select RecordID, max(RecordState)
from RecordTable a
inner join RecordStateTable b
on a.recordID = b.recordID
group by RecordID

这会提取所有失败记录,但这里的问题是 record4 值首先传递然后失败,因此传递了该记录的 max(recordstate)。我不知何故还需要为 Max(Time) 修改它,但我不知道如何。

预期结果是record3(failed),record4(failed)

【问题讨论】:

  • 所以你的结果应该只包含记录 3?还是记录 3 和 4?
  • 能否添加预期的结果
  • 你有两张桌子吗?您的查询表明您有一个 RecordTable 和一个 RecordStateTable,但您的问题表明您只有一个表。

标签: sql sql-server


【解决方案1】:

不要选择可能导致非常混乱的结果的最大状态(因为它只是字符串) - 您可以为每个 RecordID 选择 max(Time),然后只获取在最大时间处于失败状态的记录:

select T1.*
from
(
    select
        RecordID,
        max(Time) as Time
    from RecordStateTable 
    group by RecordID
) as T
    inner join RecordStateTable as T1 on T1.RecordID = T.RecordID and T1.Time = T.Time
where T1.RecordState = 'failed'

【讨论】:

    【解决方案2】:

    您可以使用分析(窗口函数)来获取每个记录 ID 的最大时间,并仅显示失败状态下的最大记录时间。

    with CTE AS (
    Select RecordID, RecordState, Time, max(time) over (partition by RecordID) mt
    FROM table)
    Select * from cte where mt = time and recordState = 'failed'
    

    【讨论】:

      【解决方案3】:

      试试这样的

      Select * From
      (
      select *,
             row_number()over(partition by RecordID order by [time] desc) as rn 
      from yourtable
      ) A
      Where RN = 1 and RecordState = 'Failed'
      

      使用Row_number 确定每个RecordID 的最大time,并与RecordState = 'Failed' 一起过滤最大时间

      【讨论】:

        【解决方案4】:

        假设您要返回每条记录的最新结果:

            declare @RecordTable TABLE (
                RecordID varchar(10),
                RecordState varchar(10),
                [Time] time
            )
        
            insert into @RecordTable
            values
                ('record1', 'failed', '1:00'),
                ('record1', 'passed', '2:00'),
                ('record2', 'passed', '2:15'),
                ('record3', 'failed', '3:00'),
                ('record4', 'passed', '4:00'),
                ('record4', 'failed', '5:00')
        
            select  a.RecordID, a.RecordState, b.[Time]
            from    @RecordTable a
                inner join (
                    select  RecordID, max([Time]) as [Time]
                    from    @RecordTable
                    group by RecordID
                ) b on b.RecordID = a.RecordID and a.[Time] = b.[Time] -- only return the most recent version
        
            --record4   failed  05:00:00.0000000
            --record3   failed  03:00:00.0000000
            --record2   passed  02:15:00.0000000
            --record1   passed  02:00:00.0000000
        

        这将获取每条记录的max(Time) 并从该行获取状态。如果您只想要失败(或通过)的记录,只需添加 where a.RecordState = 'whatever'

        【讨论】:

          【解决方案5】:

          我会使用 APPLY 来执行此操作。

          SELECT rt.RecordID, ca.RecordState
          FROM RecordTable rt
          CROSS APPLY (SELECT TOP 1 RecordState, Time
                       FROM RecordTable
                       WHERE RecordID = rt.RecordID
                       ORDER BY Time DESC) ca
          WHERE rt.Time = ca.Time AND ca.RecordState = 'failed'
          

          根据您的查询,我怀疑实际上有两个表。假设 RecordID 是 RecordTable 上的 PK,您可以将上述简化为。

          SELECT rt.RecordID, ca.RecordState
          FROM RecordTable rt
          CROSS APPLY (SELECT TOP 1 RecordState
                       FROM RecordStateTable
                       WHERE RecordID = rt.RecordID
                       ORDER BY Time DESC) ca
          WHERE ca.RecordState = 'failed'
          

          【讨论】:

            【解决方案6】:

            这将返回只有失败状态的最新时间

            select RecordID,RecordState row_number
            over (partition by recordID
            order by Time desc) as rn   from 
            yourtable
            where RecordState = 'failed' and rn = 1
            

            【讨论】:

            • 这似乎无效?当然你错过了一些逗号和括号,即使那样我也不相信你可以在 where 子句中访问 rn?
            • 这实际上对我有用/当然是的,您可以在哪里访问 rn
            • 你显然遗漏了一些东西,你有两个右括号和一个左括号。您的选择无效,我看不出 rn 如何存在于 where 子句中。也许您打算使用与 Prdp 相同的嵌入式查询?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-10
            • 2013-06-25
            • 1970-01-01
            • 1970-01-01
            • 2023-03-12
            • 1970-01-01
            相关资源
            最近更新 更多