SQL分组的前n个出现的SKU

时间:2019-07-19 21:23:17

标签: sql sql-server

我有一个所谓的billing

sku_code | invoice_id | sku_amount | sku_sale
integer  | integer    | float      | float

我想要做的是首先找到sku_code排名前350位的sku_amount

SELECT TOP 350 Sum(sku_amount) AS amt, 
       sku_code
FROM   billing 
GROUP  BY sku_code
ORDER  BY amt DESC 

然后我想用显示在上方的350 sku_code的表对整个表进行切片

我认为通过inner-join这将是某种sub-query,但我不知道语法。

有人能帮忙吗?

我要最终运行的查询是,但是它只返回上述查询中的350个sku_code。

SELECT sum(sku_amount) as amt,sku_code, invoice_id
from billing 

group by sku_code, invoice_id

order by amt DESC

给我一​​个表格,看起来应该有20-30百万行。

amt | sku_code | invoice_id

感谢您的支持!

4 个答案:

答案 0 :(得分:1)

如果我理解正确,则可以使用等级。这将为您提供所有sku_amount在前350名中的记录

SELECT * 
  FROM (
    SELECT billing.*,
           RANK() OVER ( PARTITION BY 1 ORDER BY sku_amount DESC ) rnk
    FROM   billing 
    ) TMP
 WHERE rnk <= 350

答案 1 :(得分:1)

如果您的数据库版本为2012+,则使用

OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
    [
      FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY
    ]

语法为

SELECT SUM(sku_amount) AS amt, sku_code, invoice_id
  FROM billing 
 GROUP BY sku_code, invoice_id  
 ORDER BY ROW_NUMBER() OVER (ORDER BY SUM(sku_amount) DESC)
 OFFSET 0 ROWS
 FETCH NEXT 350 ROWS ONLY

通过在order by子句中使用窗口分析功能(在这种情况下为row_number()),而无需子查询

Demo

答案 2 :(得分:1)

如果我的理解正确,那么您想要排在前350位的原始行。 JOIN就足够了:

SELECT b.*
FROM billing b JOIN
     (SELECT TOP 350 Sum(sku_amount) AS amt, 
             sku_code
      FROM billing 
      GROUP BY sku_code
      ORDER BY amt DESC 
     ) s
     ON s.sku_code = b.sku_code

答案 3 :(得分:1)

您可以通过为CTE中的行提供;with cte as( select [rn] = row_number() over( partition by [sku_code] order by [amount] desc ), * from [bill] ) select sum([sku_amount]) as [amount] from cte where [rn] <= 350; 并使用row_number小于或等于350的行来实现此目的。

查询

Customer_Dim