Sql 对表中的每一行进行排序,并对重复的行进行分组,而不重置每个组的排序

Sql 对表中的每一行进行排序,并对重复的行进行分组,而不重置每个组的排序,sql,sql-server,function,transactions,Sql,Sql Server,Function,Transactions,我已经创建了下表: 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

我已经创建了下表:

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的菜在桌子的顶部,然后是同一道菜(排名不同,如上所示)。完成后,选择下一道菜的标准应该是检查下一个等级(对于不同的菜)。每组的第一道菜是根据等级列选择的,在组内,菜应该按等级排序

当前有四道菜的桌子

我所期待的

这是MySQl特有的


这是MySQl特有的

您可以这样做:

我使用交叉应用选择最低等级,并将其用作排序器

       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
结果


您可以这样做:

我使用交叉应用选择最低等级,并将其用作排序器

       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

在这里的过程是能够加入排名和每道菜的最佳排名之间。然后可以先对最佳排名进行排序

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
你可以用这个

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

一种基于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


嗨…我忘了提到我用这个表作为例子。。。事实上,我会有100道菜…嗨…我忘了提到我用这张桌子作为例子。。。事实上,我会有100个盘子,请不要用图片。使用表格代替抱歉…新的堆栈溢出…我会记住下次请不要使用图片。使用表格代替抱歉…新的堆栈溢出…我下次会记住这一点Hi plaidDK…感谢代码…但列“Rank”是由我的代码创建的:“选择dishname,rating,Row_Number()(按等级描述排序)作为DISH的Rank”…我无法将我的代码与您的代码进行比较…它说Rank as invalidy and?然后将其包含在内部选择中statement@SridharN因为我称之为等级。只需将名称编辑为您的名称is@SridharN我现在更改了代码以使用您的排名代码。现在它是rank.嗨,plaidDK…谢谢你的代码…但是列'rank'是由我的代码创建的:“选择dishname,rating,Row_Number()Over(Order by rating desc)作为DISH中的rank”…我无法将我的代码与你的代码进行比较…它说rank是无效的,是吗?然后将其包含在内部选择中statement@SridharN因为我称之为等级。只需将名称编辑为您的名称is@SridharN我现在更改了代码以使用您的排名代码。现在它说的是等级。嗨,Richard……代码正在工作……但是等级(在本例中为“dr”)相反…我的意思是最高评级的菜排在第10位,最低评级的菜排在第1位…我们可以逆转吗???如果我们有3道以上同名的菜,所有的菜现在都被列出了…我们可以限制到3道同名的菜吗???…真的很期待你的回答吗help@SridharN:那评论毫无意义对于第一个注释…正在尝试插入一个表…dint Work可反转
dr
的顺序,反转
秩的排序
,并从第二个CTE上的
max(dr)
切换到
min(dr)
。根据具体要求,
densite\u rank()
可能比
rank()
更好。(注释中的格式和空间有限:通常最好编辑问题或答案。)嗨,Richard…代码正在运行…但是等级(在本例中为“dr”)相反…我的意思是最高评级的菜排在第10位,最低评级的菜排在第1位…我们可以逆转吗???如果我们有3道以上同名的菜,所有的菜现在都被列出了…我们可以限制到3道同名的菜吗???…真的很期待你的回答吗help@SridharN:那评论毫无意义对于第一个注释…正在尝试插入一个表…dint Work可反转
dr
的顺序,反转
秩的排序
,并从第二个CTE上的
max(dr)
切换到
min(dr)
。根据具体要求,
densite\u rank()
可能比
rank()
更好。(评论的格式和空间有限:通常最好编辑问题或答案。)这就像一场梦…但有一件事我在最初的查询中忘了提到…如果同一道菜被列出超过3次,我只想为那道菜挑选前三名…例如…如果我们有另一个1.5评级的鱼Tikka条目,它不应该与前三个鱼Tikka一起显示…但是应该根据排名在列表中稍后显示…嗨,Sarslan…更新显示了每组的前三道菜,正如预期的那样,但它从表中省略了一组中的第四道菜,并且根本没有列出它…我想要的是,如果一道菜(例如鱼苗)的第四行评级为2.5,然后,它不应该列在前三条鱼提卡清单中,而应该列在最后一道玉米宝宝菜之后。同样地,对于其他菜肴,如果他们的组中有第四道菜,我无法在这里或在我的原始问题中复制桌子…否则我会显示我想要的。我添加了桌子上的照片,每个组中有4道菜,以及我希望它们如何被列出…请看一看并帮助我…谢谢一吨萨斯兰…它工作起来像个符咒……:):)这就像一场梦…但有一件事我在最初的查询中忘了提到…如果同一道菜被列出3次以上,我只想为那道菜挑选前三名。。。