SQL:当max超过1列时如何获取行

时间:2016-06-29 16:18:48

标签: sql sql-server

我正在使用Microsoft SQL Server 2008 R2。

我有一张名为员工的表格:

create table employee (
   employee_id bigint not null primary key, 
   first_name varchar(50) not null, 
   middle_name varchar(50) null, 
   last_name varchar(50) not null
)

我有一张名为资格的表格。它有一个FK到员工表。它有一个由3列组成的唯一键:employee_id + effective_date + sequence_number。

create table eligibility (
   eligibility_id bigint not null primary key,
   employee_id bigint not null foreign key references employee (employee_id), 
   effective_date date not null,
   sequence_number int not null,
   value varchar(20) not null,
   constraint UK_eligibility unique (employee_id, effective_date, sequence_number)
)

我在员工表中有1行,其中employee_id = 1001:

insert into employee (employee_id, first_name, middle_name, last_name) values (1001, 'A', 'B', 'C')

我在同一employee_id的资格表中有4行:

insert into eligibility (eligibility_id, employee_id, effective_date, sequence_number, value) values (1, 1001, '2016-04-13', 1, 'NS')
insert into eligibility (eligibility_id, employee_id, effective_date, sequence_number, value) values (2, 1001, '2016-05-25', 1, 'EX')
insert into eligibility (eligibility_id, employee_id, effective_date, sequence_number, value) values (3, 1001, '2016-05-25', 2, 'VR')
insert into eligibility (eligibility_id, employee_id, effective_date, sequence_number, value) values (4, 1001, '2016-06-05', 1, 'LS')

从资格表中,对于给定日期,我想获得max(effective_date + sequence_number)组合的行,该行小于或等于给定日期。

示例: 对于2016-04-30日期,我希望行具有eligibility_id = 1。 对于2016-05-30日期,我希望行具有eligibility_id = 3 对于2016-06-30日期,我希望行包含eligibility_id = 4。

我已经编写了查询以获得所需的结果。这是2016-05-30日期的查询:

select * from eligibility e 
where 
    e.effective_date = (select max(e1.effective_date) 
                            from eligibility e1 
                            where e1.employee_id = e.employee_id and 
                                e1.effective_date <= '2016-05-30') AND 
    e.sequence_number = (select max(e2.sequence_number)
                            from eligibility e2 
                            where e2.employee_id = e.employee_id and 
                                e2.effective_date = e.effective_date)

查询没问题,但我想尝试以不同的方式编写它以获得相同的结果。你会推荐什么其他方式?

2 个答案:

答案 0 :(得分:3)

嗯,我会用row_number()

select e.*
from (select e.*,
             row_number() over (partition by employee_id order by effective_date desc, sequence_number desc
                               ) as seqnum
      from eligibility e
     ) e
where seqnum = 1;

答案 1 :(得分:1)

这对我来说就像TOP-1有关系:

SELECT TOP 1 WITH TIES *
FROM eligibility e
WHERE e.effective_date <= '2016-05-30'
ORDER BY e.effective_date DESC, sequence_number DESC