【问题标题】:Select Last Record Based on few criteria根据几个标准选择最后一条记录
【发布时间】:2021-03-16 08:03:55
【问题描述】:

之前

+--------+--------+---------+-------+------+
| RowNum | Status | Remarks | SetNo |      |
+--------+--------+---------+-------+------+
|      1 | Q      |         | Set 1 | Want |
|      2 | Q      |         | Set 1 | Want |
|      3 | Q      |         | Set 1 | Want |
|      4 | Q      |         | Set 1 | Want |
|      5 | W      |         | Set 1 | Want |
|      1 | W      | abc     | Set 2 |      |
|      2 | W      | abc     | Set 2 |      |
|      3 | W      | abc     | Set 2 |      |
|      4 | W      | abc     | Set 2 | Want |
|      1 | Q      |         | Set 3 | Want |
|      2 | w      | abc     | Set 3 |      |
|      3 | w      | abc     | Set 3 | Want |
+--------+--------+---------+-------+------+

如何根据 Rownum=lastnumber 和 setno 选择 Status=Q 和 Status=W? 预期结果是“想要”的行是我需要的。那些空的,将被删除

试过了:

select *
from mytable
where (RowNum != (select max(RowNum) from mytable) and status = 'W') 

【问题讨论】:

  • 您可以选择 TOP 1 并按 RowNum 降序排列。
  • 抱歉,考虑到您提供的示例数据,我无法理解您的预期结果集。
  • @NathanChampion 试过了,没用
  • @Raihan 更新了我的预期结果
  • 仍然不清楚你在找什么。你能再解释一下吗?

标签: sql sql-server subquery greatest-n-per-group


【解决方案1】:

我知道对于每个setno,您都需要所有“Q”和最新的“W”。如果是这样,您可以使用这样的窗口函数:

select *
from (
    select t.*, 
        row_number() over(partition by setno, status order by rownum desc) rn
    from mytable t
) t
where rn = 1 or status = 'Q'

【讨论】:

    【解决方案2】:

    您可能想研究窗口函数。我不完全了解您需要做什么,但我建议您这样做:

    with rowNumberedData as
    (
    SELECT *,
    ROW_NUMBER() OVER (PARTITION BY SetNo ORDER BY RowNum DESC) as RowOrder
    FROM mytable
    )
    SELECT * 
    FROM rowNumberedData
    WHERE (Status = 'Q' OR Status = 'W') AND RowOrder = 1
    

    这将做的是将RowOrder 列添加到您的数据中,其值将为 1,对于每个集合中的最大 RowNum。如果您不熟悉,可以阅读更多 herehere 以检查 with 语法是什么。

    【讨论】:

      【解决方案3】:

      这个查询应该返回正确的行

      with t_cte as (
          select t.*, 
              row_number() over(partition by setno order by rownum desc) rn
          from testTable t)
      select *
      from t_cte
      where [status] = 'Q'
            or ([status] = 'W' 
                and rn = 1);
      

      【讨论】:

        【解决方案4】:

        我理解这个问题,并且想要每组的最后一行,然后是 q 的所有行。一种方法使用row_number()

        select t.*
        from (select t.*, 
                     row_number() over (partition by setno order by rownum desc) as seqnum
              from mytable t
             ) t
        where seqnum = 1 or status = 'Q';
        

        还有其他表达方式:

        select t.*
        from mytable  t
        where t.status = 'Q' or
              t.rownum = (select max(t2.rownum)
                          from mytable t2 
                          where t2.setno = t.setno
                         );
        

        这与您尝试的方法相似。

        【讨论】:

          猜你喜欢
          • 2016-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-02
          • 2015-06-05
          • 1970-01-01
          • 1970-01-01
          • 2021-11-26
          相关资源
          最近更新 更多