SELECT
*
FROM (
SELECT
Product,
SalesAmount,
ROW_NUMBER() OVER (ORDER BY SalesAmount DESC) as RowNum,
RANK() OVER (ORDER BY SalesAmount DESC) as RankOf2007,
DENSE_RANK() OVER (ORDER BY SalesAmount DESC) as DRankOf2007
FROM (
SELECT
c.EnglishProductName as Product,
SUM(a.SalesAmount) as SalesAmount,
b.CalendarYear as CalenderYear
FROM FactInternetSales a
INNER JOIN DimDate b
ON a.OrderDateKey=b.DateKey
INNER JOIN DimProduct c
ON a.ProductKey=c.ProductKey
WHERE b.CalendarYear IN (2007)
GROUP BY c.EnglishProductName,b.CalendarYear
) Sales
) Rankings
WHERE [RankOf2007] <= 5
ORDER BY [SalesAmount] DESC
我目前正在根据销售额的总和对产品进行降序排序,并根据2007年每种产品的总销售额进行排名,如果产品1当年销售额最高,则将其排名为1等。
当前,我的数据库表看起来像图像中提到的那样(除了RankOf2008和DRankOf2008列),我希望在2008年中对2007年的前5名产品进行排名(如果前5名产品中的任何5个产品,则为空值)如上图所示,在同一表格中并排排列着2007年的2007年未售出的价格。
答案 0 :(得分:1)
也许您需要这样的东西。
首先获得所有产品的排名,然后按年份进行划分,即按年度对产品进行排名,并在CTE的帮助下获取所需数据。
WITH cte
AS (
SELECT *
FROM (
SELECT Product
,SalesAmount
,CalenderYear
,ROW_NUMBER() OVER (
PARTITION BY CalenderYear ORDER BY SalesAmount DESC
) AS RowNum
,RANK() OVER (
PARTITION BY CalenderYear ORDER BY SalesAmount DESC
) AS RankOf2007
,DENSE_RANK() OVER (
PARTITION BY CalenderYear ORDER BY SalesAmount DESC
) AS DRankOf2007
FROM (
SELECT c.EnglishProductName AS Product
,SUM(a.SalesAmount) AS SalesAmount
,b.CalendarYear AS CalenderYear
FROM FactInternetSales a
INNER JOIN DimDate b ON a.OrderDateKey = b.DateKey
INNER JOIN DimProduct c ON a.ProductKey = c.ProductKey
--WHERE b.CalendarYear IN (2007)
GROUP BY c.EnglishProductName
,b.CalendarYear
) Sales
) Rankings
--WHERE [RankOf2007] <= 5
--ORDER BY [SalesAmount] DESC
)
SELECT a.*
,b.DRankOf2007 AS [DRankOf2008]
,b.RankOf2007 AS [RankOf2008]
FROM cte a
LEFT JOIN cte b ON a.Product = b.Product
AND b.CalenderYear = 2008
WHERE a.CalenderYear = 2007
AND a.[RankOf2007] <= 5
答案 1 :(得分:0)
在最里面的查询中使用条件汇总(即,选择年份和有条件地合计年份之一):
select
p.productkey,
p.englishproductname as product,
ranked.salesamount2007,
ranked.salesamount2008,
ranked.rankof2007,
ranked.rankof2008
from
(
select
productkey,
salesamount2007,
salesamount2008,
rank() over (order by salesamount2007 desc) as rankof2007,
rank() over (order by salesamount2008 desc) as rankof2008
from
(
select
s.productkey,
sum(case when d.calendaryear = 2007 then s.salesamount end) as salesamount2007,
sum(case when d.calendaryear = 2008 then s.salesamount end) as salesamount2008
from factinternetsales s
inner join dimdate d on d.datekey = s.orderdatekey
where d.calendaryear in (2007, 2008)
group by s.productkey
) aggregated
) ranked
join dimproduct p on p.productkey = ranked.productkey
where ranked.rankof2007 <= 5
order by ranked.rankof2007 desc;
对于2008年没有产品行的情况,salesamount2008
将为空。在标准SQL中,我们将在ORDER BY
子句中考虑这一点:
rank() over (order by salesamount2008 desc nulls last) as rankof2008
但是SQL Server不符合此处的SQL标准,并且在NULLS FIRST/LAST
子句中不具有ORDER BY
。幸运的是,当按降序排序时,它将最后排序空值,因此它隐式地执行了我们在这里想要的操作。
顺便说一句:我们可以在一个步骤中进行汇总和排名,但是在这种情况下,我们必须重复SUM
表达式。是一步一步(较短的查询)还是一步一步(无重复的表达式)来完成此操作。