Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在ms sql中不使用秩/行数函数而获得每个类别的前2名_Sql Server - Fatal编程技术网

Sql server 如何在ms sql中不使用秩/行数函数而获得每个类别的前2名

Sql server 如何在ms sql中不使用秩/行数函数而获得每个类别的前2名,sql-server,Sql Server,我在MS-SQL 2016上 我有一个场景,要求每个组获得前2名的已支付奖金,不允许排名和行数,以下是您可以用来生成表和数据的代码: Create table Freelancer (id int, fl_name varchar(20), bonus int, fl_group varchar(50)) insert into Freelancer (id, fl_name, bonus, fl_group) Values (1, 'John', 1000, 'SQL') insert i

我在MS-SQL 2016上

我有一个场景,要求每个组获得前2名的已支付奖金,不允许排名和行数,以下是您可以用来生成表和数据的代码:

Create table Freelancer (id int, fl_name varchar(20), bonus int, fl_group varchar(50))


insert into Freelancer (id, fl_name, bonus, fl_group) Values (1, 'John', 1000, 'SQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (2, 'Jane', 990, 'MySQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (3, 'Jimmy', 320, 'Oracle')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (4, 'Jeff', 802, 'DynamoDB')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (5, 'Johnathan', 2345, 'Hive')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (6, 'Jeffery', 321, 'RDS')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (7, 'Jane2', 1990, 'MySQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (8, 'Jimmy3', 321, 'Oracle')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (9, 'Jeff4', 803, 'DynamoDB')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (10, 'Johnathan5', 345, 'Hive')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (11, 'Jeffery', 32, 'RDS')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (12, 'Jane3', 1190, 'MySQL')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (13, 'Jimmy4', 322, 'Oracle')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (14, 'Jeff5', 8002, 'DynamoDB')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (15, 'Johnathan6', 235, 'Hive')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (16, 'Jeffery7', 31, 'RDS')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (17, 'Jack', 34, 'Redshift')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (18, 'Jennifer', 121, 'Aurora')
insert into Freelancer (id, fl_name, bonus, fl_group) Values (19, 'Jackson', 425, 'Redis')
例如,在DynamoDB组中,将拾取Jeff58002和Jeff4803

尽管我在条款中指定了top 2,但我已经尝试了以下内容,并且没有返回所需的结果:

select *
from Freelancer t
where t.ID in (
    select top 2 ID
    from Freelancer tt
    where tt.fl_name = t.fl_name
    order by tt.bonus desc
    )
order by fl_group, bonus desc
我的结果是:


您应该比较外部查询和子查询之间的奖金,并且应该使用组进行关联

SELECT *
FROM Freelancer t
WHERE t.bonus IN (
    SELECT TOP 2 tt.bonus
    FROM Freelancer tt
    WHERE tt.fl_group = t.fl_group
    ORDER BY tt.bonus DESC
)
ORDER BY
    fl_group,
    bonus DESC;

如果可以使用其他窗口函数,请尝试用窗口总和替换行数行为:


使用相关子查询,该子查询为每一行返回该组中具有更高奖金的行数:

select t.* from Freelancer t
where 1 >= (select count(*) from Freelancer tt where tt.fl_group = t.fl_group and tt.bonus > t.bonus)
order by t.fl_group, t.bonus desc
看。 结果:

您可以使用应用程序:


请尝试此解决方案,在此解决方案中听到我已将fl_组合并为您的类别,并获得fl_组明智的前2项记录

声明临时表

插入样本数据

分类排名前2的记录

输出

在这里,您还可以使用联接而不是子查询来提高查询性能

有关详细信息,您可以尝试此解决方案,请访问以下URL:


我希望这对你有用

你能使用其他窗口功能吗?你真的需要交叉发布吗?您在SSC上得到的答案有什么问题?非常感谢,如果最终订单在fl_group上,然后在desc中获得奖金,这会更有意义。但根据您的脚本,这很容易做到:谢谢mdivk,如果有帮助,请标记此答案,所以其他人也可以学习并得到这类问题的答案。这个答案是错误的,显然是报告了错误的结果。集团DynamoDB的最高奖金是8002。嗨,蒂姆,你就在你的位置,事实上,在上面的回答中,我已经根据fl_集团和id订购了记录,但是你可以理解我们可以根据需要在哪里申请订单,在这种情况下,我们还需要包括奖金栏,但我认为这应该是可以理解的,我们可以根据需要进行更改,这只是示例提示或归档此类需求的方法。谢谢你。大部分贴出的答案都达到了预期的效果,我不能把所有答案都当作答案,但谢谢你的帮助enlightening@mdivk是的,只能接受一个答案。我很高兴你有一个解决你的问题的办法。大多数张贴的答案都得到了预期的结果,我不能把所有的答案都当作答案,但谢谢你的启发。大多数张贴的答案都得到了预期的结果,我不能把所有的答案当作答案,但谢谢你的启发
select t.* from Freelancer t
where 1 >= (select count(*) from Freelancer tt where tt.fl_group = t.fl_group and tt.bonus > t.bonus)
order by t.fl_group, t.bonus desc
> id | fl_name    | bonus | fl_group
> -: | :--------- | ----: | :-------
> 18 | Jennifer   |   121 | Aurora  
> 14 | Jeff5      |  8002 | DynamoDB
>  9 | Jeff4      |   803 | DynamoDB
>  5 | Johnathan  |  2345 | Hive    
> 10 | Johnathan5 |   345 | Hive    
>  7 | Jane2      |  1990 | MySQL   
> 12 | Jane3      |  1190 | MySQL   
> 13 | Jimmy4     |   322 | Oracle  
>  8 | Jimmy3     |   321 | Oracle  
>  6 | Jeffery    |   321 | RDS     
> 11 | Jeffery    |    32 | RDS     
> 19 | Jackson    |   425 | Redis   
> 17 | Jack       |    34 | Redshift
>  1 | John       |  1000 | SQL     
SELECT DISTINCT f2.*
FROM Freelancer f CROSS APPLY
     ( SELECT TOP (2) f1.* 
       FROM Freelancer f1
       WHERE f1.fl_group = f.fl_group
       ORDER BY f1.bonus DESC
     ) f2
ORDER BY f2.fl_group, f2.bonus DESC;
declare @Freelancer as TABLE (id int, fl_name varchar(20), bonus int, fl_group varchar(50))
insert into @Freelancer(id, fl_name, bonus, fl_group) Values(1, 'John', 1000, 'SQL')
,(2, 'Jane', 990, 'MySQL')
,(3, 'Jimmy', 320, 'Oracle')
,(4, 'Jeff', 802, 'DynamoDB')
,(5, 'Johnathan', 2345, 'Hive')
,(6, 'Jeffery', 321, 'RDS')
,(7, 'Jane2', 1990, 'MySQL')
,(8, 'Jimmy3', 321, 'Oracle')
,(9, 'Jeff4', 803, 'DynamoDB')
,(10, 'Johnathan5', 345, 'Hive')
,(11, 'Jeffery', 32, 'RDS')
,(12, 'Jane3', 1190, 'MySQL')
,(13, 'Jimmy4', 322, 'Oracle')
,(14, 'Jeff5', 8002, 'DynamoDB')
,(15, 'Johnathan6', 235, 'Hive')
,(16, 'Jeffery7', 31, 'RDS')
,(17, 'Jack', 34, 'Redshift')
,(18, 'Jennifer', 121, 'Aurora')
,(19, 'Jackson', 425, 'Redis')
select *
from @Freelancer t
where t.ID in (
    select top 2 ID
    from @Freelancer tt
    where tt.fl_group = t.fl_group
    order by id
    )
order by fl_group,id