[英]Rank each row in a table and group the rows for duplicates without resetting the rank for each group
我创建了下表:
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
我希望排名第一的菜在表的顶部,然后是相同的菜(排名不同,如上所示)。 一旦完成,选择下一个菜的标准应该是检查下一个等级(对于另一个菜)。 根据等级列选择每个组的第一个菜,并且在组中,菜应按等级排序。
四盘电流桌
请点击图片
我期待什么
请点击图片
您可以这样做:
我使用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
您可以使用它。
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
单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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.