我有一张像所谓的桌子
billing
sku_code | invoice_id | sku_amount | sku_sale
integer | integer | float | float
我想做的是首先找到前 350 名
sku_code
by 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_codes。
SELECT sum(sku_amount) as amt,sku_code, invoice_id
from billing
group by sku_code, invoice_id
order by amt DESC
这给了我一个看起来应该有大约 20-3000 万行的表。
amt | sku_code | invoice_id
如果我理解正确的话,您需要前 350 个 sku 的原始行。 一个
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
如果我理解正确,你可以只使用排名。这将为您提供 sku_amount 位于前 350 名的所有记录
SELECT *
FROM (
SELECT billing.*,
RANK() OVER ( PARTITION BY 1 ORDER BY sku_amount DESC ) rnk
FROM billing
) TMP
WHERE rnk <= 350
如果您的数据库版本是 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()
),无需子查询
您可以通过为
row_number
内的行指定 CTE
并使用 row_number 小于或等于 350 的行来实现此目的。
查询
;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;