SQL:截断组中的最高值

时间:2018-04-11 13:35:43

标签: sql

在下面的示例数据集中,我很好奇是否有办法删除每个季度的两组最高值。对于下面的数据集....删除2016Q1 MOB 26和25 ... 2016Q2删除所有MOB 19和18 ...这在SQL中是否可行?

Quarter MOB Amount
2016Q1  26  18000
2016Q1  25  14300
2016Q1  24  8520
2016Q1  23  15200
2016Q1  22  3000
2016Q2  19  6000
2016Q2  19  5500
2016Q2  18  7800
2016Q2  18  2220
2016Q2  17  9530
2016Q2  17  4000
2016Q2  16  8900
2016Q2  16  4550

2 个答案:

答案 0 :(得分:0)

假设您使用SQL-Server,可以使用CTERow_number()来识别两个最高集。

测试数据

create table dbo.highest (Kvartal varchar(50),MOB int , amount int )
insert into dbo.highest
values
('2016Q1', 26 ,18000),
('2016Q1', 25 ,14300),
('2016Q1', 24 ,8520 ),
('2016Q1', 23 ,15200), 
('2016Q1', 22 ,3000 ),
('2016Q2', 19 ,6000 ),
('2016Q2', 19 ,5500 ),
('2016Q2', 18 ,7800 ),
('2016Q2', 18 ,2220 ),
('2016Q2', 17 ,9530 ),
('2016Q2', 17 ,4000 ),
('2016Q2', 16 ,8900 ),
('2016Q2', 16 ,4550 )
  

感谢dnoeth同时指定可以使用dense_rank。

SQL删除Dense_Rank()

with deletehighest as (
select *,DENSE_RANK() over(partition by Kvartal order by MOB desc) as densern from  dbo.highest
)

delete from deletehighest
where densern <= 2

SQL删除Row_number()

  with deletehighest as (
select ROW_NUMBER() over(partition by kvartal order by MOB desc) as rn,MOB,Kvartal from (
select distinct Kvartal,MOB from dbo.highest
) z
)

delete from a
from dbo.highest a
inner join deletehighest b on a.Kvartal = b.Kvartal and a.MOB = b.MOB and b.rn in(1,2)

答案 1 :(得分:0)

对于MySQL:

DELETE tq FROM tq
  INNER JOIN (
               SELECT *
               FROM (SELECT
                       t.*,
                       CASE
                       WHEN @quarter != t.quarter
                         THEN @rownum := 1
                       ELSE CASE WHEN @mob != t.mob
                         THEN @rownum := @rownum + 1
                            ELSE @rownum := @rownum
                            END
                       END                   AS rank,
                       @quarter := t.quarter AS var_quarter,
                       @mob := t.mob         AS var_mob
                     FROM Tq t
                       JOIN (SELECT
                               @rownum := NULL,
                               @quarter := '',
                               @mob := '') r
                     ORDER BY t.quarter, t.mob DESC) x
               WHERE x.rank <= 2) tqlimit ON tq.quarter = tqlimit.quarter AND tq.mob = tqlimit.mob;