2016-06-29 5 views
0

Ich arbeite mit Microsoft SQL Server 2008 R2.SQL: Wie bekomme ich die Zeile, wenn max auf mehr als 1 Spalte

Ich habe eine Tabelle Mitarbeiter genannt:

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 
) 

Ich habe eine Tabelle Förderfähigkeit benannt. Es hat einen FK zu Mitarbeitertisch. Es hat einen eindeutigen Schlüssel mit 3 Spalten: 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) 
) 

Ich habe 1 row in Mitarbeiter Tabelle mit employee_id = 1001:

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

Ich habe 4 Reihen in Förderfähigkeit Tabelle für die gleiche employee_id:

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') 

Aus die Berechtigungstabelle, für ein bestimmtes Datum möchte ich die Zeile mit dem Maximum erhalten (effektives_Datum + Sequenznummer) c Kombination, die kleiner oder gleich dem angegebenen Datum ist.

Beispiele: Für 2016-04-30 Datum I mit eligibility_id = 1. Für 2016-05-30 Datum der Zeile möchte ich würde die Zeile mit eligibility_id wollen = 3.
Für 2016-06-30 Datum eligibility_id die Zeile möchte ich würde = 4.

Ich habe die Abfrage geschrieben, um die gewünschten Ergebnisse zu erhalten. Dies ist die Abfrage für 2016-05-30 Datum:

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) 

Die Abfrage ist ok, aber ich will versuchen, es in irgendeiner anderen Weise schreiben die gleichen Ergebnisse zu erhalten. Welche andere Art würden Sie empfehlen?

+0

Welche Eigenschaften Ihrer Abfrage, die Sie durch Umschreiben es zu verbessern hoffen? "Ein anderer Weg, um die gleichen Ergebnisse zu erzielen" bietet unendlich viele Möglichkeiten. –

+0

@JohnBollinger Ich mag die 2 Mal nicht, die ich Berechtigungstabelle in der Where-Klausel verwende – srh

Antwort

3

Hmmm, ich würde row_number() verwenden:

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

Das sieht für mich wie TOP-1 mit Verbindungen:

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