一种将嵌套排名应用于几列 SUM 的更优雅的方法
A more elegant way to apply Nested Ranking over SUM of a few columns
是否有更优雅的方法来对几个不同的列应用嵌套排名,先按最左边列的总计排序,然后再按该组内的总计排序?我提供了关于示例数据结构和所需状态的屏幕截图。
现在,我正在使用三个不同的查询(首先按总计对地区进行排名。然后按州总数排名第二,等等,第三按城市排名)
维护起来很痛苦,特别是如果我需要修改排名的顺序以及日期window。 (考虑按月计算的销售额、按 YTD 计算的销售额等)
使用 RANK 和 windows 函数和分区,我可以很容易地获得区域内城市排名,但要同时获得州排名和地区排名,我开始挣扎。
对于那些好奇的人,我在 SQL 而不是 Tableau 中进行排名,因为几乎不可能将排名与使用 Tableau window 函数设置的嵌套 Top N + Other 混合使用或细节层次。
CREATE TABLE RankingTest (
Region NVarChar(15),
[State] NVarChar(2),
City NVarChar(50),
Sales Int
);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','NY','New York',32);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','NY','New York',3);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','NY','Queens',4);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','MA','Boston',6);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','FL','Miama',7);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','WA','Seattle',13);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','WA','Bellevue',6);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','WA','Kirkland',8);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','OR','Portland',11);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','OR','Salem',3);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','CA','San Franscisco',6);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','CA','San Franscisco',9);
当前查询:
WITH RegionRank AS (
SELECT Region,
DENSE_RANK() OVER (ORDER By SUM(Sales) DESC) AS Rank,
SUM(Sales) AS Sales
FROM RankingTest
GROUP BY Region
),
StateRank AS (
SELECT RT.Region, State,
DENSE_RANK() OVER (PARTITION BY RR.Rank ORDER BY RR.Rank, SUM(RT.Sales) DESC) AS Rank,
SUM(RT.Sales) AS Sales
FROM RankingTest RT LEFT JOIN RegionRank RR ON RT.Region = RR.Region
GROUP BY RT.Region, RR.Rank, State
),
CityRank AS (
SELECT RT.Region, RR.Rank RegionRank, RR.Sales RegionSales, RT.State,
SR.Rank StateRank, SR.Sales StateSales, City,
DENSE_RANK() OVER (PARTITION BY RR.Rank, SR.Rank ORDER BY RR.Rank, SR.Rank, SUM(RT.Sales) DESC) AS
Rank,
SUM(RT.Sales) AS Sales
FROM RankingTest RT
LEFT JOIN RegionRank RR ON RT.Region = RR.Region
LEFT JOIN StateRank SR ON RT.Region = SR.Region AND RT.State = SR.State
GROUP BY RT.Region, RR.Rank, RR.Sales, RT.State, SR.Rank, SR.Sales, City
)
SELECT * FROM CityRank
嵌套查询应该可以解决问题:
SELECT *,
DENSE_RANK() OVER( ORDER BY SalesRegion DESC ) AS RankRegion,
DENSE_RANK() OVER( PARTITION BY Region ORDER BY SalesState DESC ) AS RankState,
DENSE_RANK() OVER( PARTITION BY Region, State ORDER BY SalesCity DESC ) AS RankCity
FROM(
SELECT DISTINCT Region, State, City,
SUM( Sales ) OVER( PARTITION BY city, State, Region ) as SalesCity,
SUM( Sales ) OVER( PARTITION BY State, Region ) as SalesState,
SUM( Sales ) OVER( PARTITION BY Region ) as SalesRegion
FROM RankingTest ) AS DistinctSales
ORDER BY RankRegion, RankState, RankCity
请注意,DISTINCT Region, State, City
在这里充当 GROUP BY
。
是否有更优雅的方法来对几个不同的列应用嵌套排名,先按最左边列的总计排序,然后再按该组内的总计排序?我提供了关于示例数据结构和所需状态的屏幕截图。
现在,我正在使用三个不同的查询(首先按总计对地区进行排名。然后按州总数排名第二,等等,第三按城市排名) 维护起来很痛苦,特别是如果我需要修改排名的顺序以及日期window。 (考虑按月计算的销售额、按 YTD 计算的销售额等)
使用 RANK 和 windows 函数和分区,我可以很容易地获得区域内城市排名,但要同时获得州排名和地区排名,我开始挣扎。
对于那些好奇的人,我在 SQL 而不是 Tableau 中进行排名,因为几乎不可能将排名与使用 Tableau window 函数设置的嵌套 Top N + Other 混合使用或细节层次。
CREATE TABLE RankingTest (
Region NVarChar(15),
[State] NVarChar(2),
City NVarChar(50),
Sales Int
);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','NY','New York',32);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','NY','New York',3);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','NY','Queens',4);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','MA','Boston',6);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('East','FL','Miama',7);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','WA','Seattle',13);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','WA','Bellevue',6);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','WA','Kirkland',8);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','OR','Portland',11);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','OR','Salem',3);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','CA','San Franscisco',6);
INSERT INTO RankingTest (Region, [state], city, Sales) Values ('West','CA','San Franscisco',9);
当前查询:
WITH RegionRank AS (
SELECT Region,
DENSE_RANK() OVER (ORDER By SUM(Sales) DESC) AS Rank,
SUM(Sales) AS Sales
FROM RankingTest
GROUP BY Region
),
StateRank AS (
SELECT RT.Region, State,
DENSE_RANK() OVER (PARTITION BY RR.Rank ORDER BY RR.Rank, SUM(RT.Sales) DESC) AS Rank,
SUM(RT.Sales) AS Sales
FROM RankingTest RT LEFT JOIN RegionRank RR ON RT.Region = RR.Region
GROUP BY RT.Region, RR.Rank, State
),
CityRank AS (
SELECT RT.Region, RR.Rank RegionRank, RR.Sales RegionSales, RT.State,
SR.Rank StateRank, SR.Sales StateSales, City,
DENSE_RANK() OVER (PARTITION BY RR.Rank, SR.Rank ORDER BY RR.Rank, SR.Rank, SUM(RT.Sales) DESC) AS
Rank,
SUM(RT.Sales) AS Sales
FROM RankingTest RT
LEFT JOIN RegionRank RR ON RT.Region = RR.Region
LEFT JOIN StateRank SR ON RT.Region = SR.Region AND RT.State = SR.State
GROUP BY RT.Region, RR.Rank, RR.Sales, RT.State, SR.Rank, SR.Sales, City
)
SELECT * FROM CityRank
嵌套查询应该可以解决问题:
SELECT *,
DENSE_RANK() OVER( ORDER BY SalesRegion DESC ) AS RankRegion,
DENSE_RANK() OVER( PARTITION BY Region ORDER BY SalesState DESC ) AS RankState,
DENSE_RANK() OVER( PARTITION BY Region, State ORDER BY SalesCity DESC ) AS RankCity
FROM(
SELECT DISTINCT Region, State, City,
SUM( Sales ) OVER( PARTITION BY city, State, Region ) as SalesCity,
SUM( Sales ) OVER( PARTITION BY State, Region ) as SalesState,
SUM( Sales ) OVER( PARTITION BY Region ) as SalesRegion
FROM RankingTest ) AS DistinctSales
ORDER BY RankRegion, RankState, RankCity
请注意,DISTINCT Region, State, City
在这里充当 GROUP BY
。