【问题标题】:Get top n row of each group of two columns获取每组两列的前 n 行
【发布时间】:2016-12-16 20:54:00
【问题描述】:

这个问题不同于Get top 1 row of each group。在我的问题中,每组由两列(col1col2)组成,而在他的问题中,每组仅由一列(col1)组成。我也尝试修改他问题中的答案,但失败了。

例子:

假设n = 1

输入:

    col1  col2 x  Amt
    A     B    x1 100
    A     B    x2 200
    C     D    x3 400
    C     D    x4 500
    ...more data ...

输出:

    col1  col2 x  Amt
    A     B    x2 200
    C     D    x4 500
    ...more data ...

我尝试了什么...select *, row_numne() over ( partition by (col1, col2) order by ...

【问题讨论】:

    标签: sql sql-server sql-server-2008


    【解决方案1】:

    您仍然可以在CTE 中使用row_number。这个想法是根据您的分组获取所有行,即

    declare @count int = 1
    with cte as(
        select 
            col1,
            col2,
            x,
            Amt,
            row_number() over (partition by col1, col2 order by Amt desc) as rn
        from yourTable)
    
    select 
        col1,
        col2,
        x,
        Amt
    from cte
    where rn <= @count
    

    【讨论】:

      【解决方案2】:

      为什么简单的 max 不适合你?

      select col1, col2, max(x), Max(Amt) from yourtable
        group by col1, col2
      

      【讨论】:

      • MAX() 适用于样本数据,但是否可以保证顶行中的所有数据(与分组相反)列对于任何可能的分组集始终具有最大值?例如,如果您的查询在每张发票中查找包含最多项目的行,如果 MAX() 为 1 行包含 100 个 1.00 美元项目和 1 行包含 1 个 100 美元项目的发票,则将报告包含 100 个 100 美元项目的行用过的。而是需要互相关。
      【解决方案3】:
      Declare @Top int = 1
      
      Select col1,col2,x,Amt 
       From  (
               Select *
                     ,RN=Row_Number() over (Partition By Col1,Col2 Order By Amt Desc) 
               From  YourTable ) A
       Where RN<=@Top
      

      返回

      col1    col2    x   Amt
      A       B       x2  200
      C       D       x4  500
      

      【讨论】:

      • 可能比 CTE 快。更好的主意
      • @scsimon 无法想象有什么不同...如果有的话
      • @scsimon 有点无聊的问题。我只有一个引起了我的注意stackoverflow.com/questions/41190208/…
      【解决方案4】:

      这里是 CROSS APPLY 选项,带有测试表以确认其功能:

      DECLARE @MyTable TABLE (Col1 varchar(4) not null, Col2 varchar(4) not null, x varchar(8) not null, amt int not null)
      
      INSERT INTO @myTable VAlues ('A', 'B', 'x1', 100)
      INSERT INTO @myTable VAlues ('A', 'B', 'x2', 200)
      INSERT INTO @myTable VAlues ('C', 'D', 'x4', 400)
      INSERT INTO @myTable VAlues ('C', 'D', 'x3', 500)
      
      
      DECLARE @n int
      SET @n = 1
      
      SELECT DISTINCT 
          m.Col1,
          m.Col2,
          m2.x,
          m2.Amt
      FROM @MyTable m
      CROSS APPLY (
          SELECT TOP(@n) Amt, x
          FROM @MyTable 
          WHERE col1 = m.Col1
              AND col2 = m.col2
          ORDER BY Amt Desc, x Desc
          ) m2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-13
        • 2021-01-18
        • 2013-04-25
        • 2016-01-23
        • 1970-01-01
        • 1970-01-01
        • 2021-09-01
        相关资源
        最近更新 更多