对表中的每一行进行排名,并将行分组为重复项,而不重置每个组的排名
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对表中的每一行进行排名,并将行分组为重复项,而不重置每个组的排名相关的知识,希望对你有一定的参考价值。
我跟我一起创建了下表:
dishname rating rank
Fish Fry 5.0 1
Tandoori Chicken 4.8 2
Tandoori Chicken 4.6 3
Paneer Tikka 4.5 4
Baby Corn 4.2 5
Fish Fry 4.1 6
Paneer Tikka 3.9 7
Baby Corn 3.1 8
Fish Fry 2.9 9
Paneer Tikka 2.3 10
*假设每道菜都来自不同的餐厅
使用的代码:
Select dishname,
rating,
Row_Number() Over(Order By rating desc) as Rank
From DISH
这就是我想要实现的目标:
dishname rating rank
Fish Fry 5.0 1
Fish Fry 4.1 6
Fish Fry 2.9 9
Tandoori Chicken 4.8 2
Tandoori Chicken 4.6 3
Paneer Tikka 4.5 4
Paneer Tikka 3.9 7
Paneer Tikka 2.3 10
Baby Corn 4.2 5
Baby Corn 3.1 8
我希望将等级为1的菜放在桌子的顶部,然后是相同的菜(如上所示,具有不同的等级)。一旦完成,那么选择下一道菜的标准应该是检查下一个等级(对于不同的菜)。每组的第一道菜是根据Rank栏选择的,并且在组内,菜肴应按等级排序。
有四种菜肴的当前餐桌 Please click for picture
我期待什么 Please click for picture
答案
你可以用它。
DECLARE @DISH TABLE ( dishname varchar(20), rating decimal(18,2) )
INSERT INTO @DISH VALUES
('Fish Fry' ,5.0),
('Tandoori Chicken' ,4.8),
('Tandoori Chicken' ,4.6),
('Paneer Tikka' ,4.5),
('Baby Corn' ,4.2),
('Fish Fry' ,4.1),
('Paneer Tikka' ,3.9),
('Baby Corn' ,3.1),
('Fish Fry' ,2.9),
('Fish Fry' ,1.9),
('Paneer Tikka' ,2.3),
('Tandoori Chicken' ,3.2),
('Tandoori Chicken' ,1.7),
('Paneer Tikka' ,2.0)
SELECT dishname, rating, Rank
FROM (
SELECT *,
Row_Number() Over(Order By SubRank, rating desc) as Rank,
MAX(rating) OVER(PARTITION BY SubRank, dishname) as FirstOrdeR
FROM (
Select dishname,
rating,
((Row_Number() Over(PARTITION BY dishname ORDER BY rating desc))-1) / 3 as SubRank
From @DISH
) AS T
) AS X
ORDER BY SubRank, FirstOrder DESC, Rank
结果:
dishname rating Rank
-------------------- --------------------------------------- --------------------
Fish Fry 5.00 1
Fish Fry 4.10 6
Fish Fry 2.90 10
Tandoori Chicken 4.80 2
Tandoori Chicken 4.60 3
Tandoori Chicken 3.20 8
Paneer Tikka 4.50 4
Paneer Tikka 3.90 7
Paneer Tikka 2.30 11
Baby Corn 4.20 5
Baby Corn 3.10 9
Paneer Tikka 2.00 12
Fish Fry 1.90 13
Tandoori Chicken 1.70 14
另一答案
你可以这样做:
我使用CROSS APPLY选择最小排名,并将其用作排序顺序。
declare @myt table (dishname nvarchar(50), rating float, rank int)
insert into @myt
values
('Fish Fry' ,5.0 , 1),
('Tandoori Chicken' ,4.8 , 2),
('Tandoori Chicken' ,4.6 , 3),
('Paneer Tikka' ,4.5 , 4),
('Baby Corn' ,4.2 , 5),
('Fish Fry' ,4.1 , 6),
('Paneer Tikka' ,3.9 , 7),
('Baby Corn' ,3.1 , 8),
('Fish Fry' ,2.9 , 9),
('Paneer Tikka' ,2.3 ,10)
select z.Dishname,rating,[rank] from (
select *,ROW_NUMBER() over(partition by dishname order by [Rank] asc,rating desc) rn from (
Select dishname,
rating,
Row_Number() Over(Order By rating desc) as [Rank]
From @myt
)X
) z
cross apply (select MIN(rank) as sortorder,dishname from @myt s
where s.dishname = z.dishname group by dishname) f
order by sortorder,rn
结果
另一答案
这里的过程是能够在每个菜的排名和最佳排名之间加入。然后可以先排序最好的排名。
with ranking as (
select dishname, rating, rank() over(order by rating) as dr
from Dish
), topRanking as (
select dishname, max(dr) as maxRank
from ranking
group by dishname
)
select r.dishname, r.rating
from ranking r
inner join topRanking tr on tr.dishname = r.dishname
order by maxRank desc, rating desc
另一答案
基于单CTE的方法,虽然可能比其他答案效率低一点:
--DECLARE @TABLE TABLE(dishname varchar(10), rating decimal(2,1))
--INSERT INTO @TABLE VALUES ('Fish', 5.0), ('Chicken', 4.8), ('Chicken', 4.6), ('Tikka', 4.5), ('Corn', 4.2), ('Fish', 4.1), ('Tikka', 3.9), ('Corn', 3.1), ('Fish', 2.9), ('Tikka', 2.3) /* extra records */ , ('Fish', 1.9), ('Chicken', 3.2), ('Chicken', 1.7), ('Tikka', 2.0)
;WITH CTE AS (
SELECT
*
, [Rank] = ROW_NUMBER() OVER(ORDER BY rating DESC)
, [Group] = (ROW_NUMBER() OVER(PARTITION BY dishname ORDER BY rating DESC) - 1) / 3
FROM @TABLE
)
SELECT *
FROM CTE AS A
ORDER BY [Group], (SELECT MIN([Rank]) FROM CTE AS B WHERE A.dishname = B.dishname AND A.[Group] = B.[Group]), rating DESC
另一答案
Select dishname,rating, Row_Number() Over as Rank From DISH where order by dishname('Fish Fry','Tandoori Chicken','Panner Tikka','Baby Corn') order by Over DESC;
这是mysql特有的
以上是关于对表中的每一行进行排名,并将行分组为重复项,而不重置每个组的排名的主要内容,如果未能解决你的问题,请参考以下文章