我需要每年退回十大产品,我如何通过以下查询来完成这项工作?
SELECT
DP.ProductID
, DP.Name
, Year(FS.OrderDate) as TheYear
, FS.OrderQty
, FS.OrderAmount
FROM dbo.DimProduct AS DP
LEFT JOIN dbo.FactSales as FS on FS.ProductID = DP.ProductID
答案 0 :(得分:3)
如果您的RDBMS支持Window Functions
SELECT ProductID,
Name,
TheYear,
OrderQty,
OrderAmount
FROM
(
SELECT DP.ProductID
,DP.Name
,Year(FS.OrderDate) as TheYear
,FS.OrderQty
,FS.OrderAmount,
,ROW_NUMBER() OVER() (PARTITION BY Year(FS.OrderDate)
ORDER BY FS.OrderQty DESC) rn
FROM dbo.DimProduct AS DP
LEFT JOIN dbo.FactSales as FS
on FS.ProductID = DP.ProductID
) s
WHERE rn <= 10
ORDER BY TheYear
当前查询会根据10
为每TheYear
个FS.OrderQty
个产品提供ROW_NUMBER()
个产品,因为您没有提及有关如何整理记录的条件。
Year(FS.OrderDate)
( a RANKING函数)将为每个组生成一个数字序列,在本例中为FS.OrderQty
,根据{{1}进行整理}。然后将根据生成的序列的值过滤掉记录。
但是,如果ROW_NUMBER()
不会在具有相同TIE
的记录上生成FS.OrderQty
。如果您希望对其进行处理,请使用DENSE_RANK()
代替ROW_NUMBER()
。
答案 1 :(得分:3)
您希望使用函数row_number()
获得前10名。这假设OrderQty
定义了前10名:
select t.*
from (SELECT DP.ProductID, DP.Name, Year(FS.OrderDate) as TheYear, FS.OrderQty, FS.OrderAmount,
row_number() over (partition by Year(FS.OrderDate)
order by fs.OrderAmount desc
) as seqnum
FROM dbo.DimProduct DP LEFT JOIN
dbo.FactSales FS
on FS.ProductID = DP.ProductID
) t
where seqnum <= 10;
函数row_number()
枚举行,从1开始。它在每个组中重新开始,由partition by
子句(在您的情况下为年份)定义。数字的排序基于order by
子句(在您的情况下为fs.OrderAmount desc
)。因此,每年十个最佳产品的数字为1-10,而where
条款只选择它们。
答案 2 :(得分:0)
SELECT
DP.ProductID
, DP.Name
, Year(FS.OrderDate) as TheYear
, FS.OrderQty
, FS.OrderAmount
, (FS.OrderQty * FS.OrderAmount) AS FS.Total
FROM dbo.DimProduct AS DP
LEFT JOIN dbo.FactSales as FS on FS.ProductID = DP.ProductID
GROUP BY TheYear, DP.ProductID, FS.Total
ORDER BY FS.Total DESC
WHERE seqnum <= 10;