Это плохо сформулированный заголовок, но я не могу придумать ничего лучшего, извините!
У нас есть таблица, которая выглядит примерно так (обрезано для краткости):
create table Appointment (
AppointmentId int not null identity(1, 1),
CustomerId int not null,
AppointmentDate date not null,
constraint PK_Appointment primary key (AppointmentId),
constraint FK_Appointment_Customer foreign key (CustomerId) references Customer(CustomerId)
)
Мы пытаемся написать запрос, в котором будут найдены сведения обо всех клиентах, у которых была ВТОРАЯ встреча в заданном диапазоне дат. Обратите внимание, что клиенты могли иметь две встречи в одну и ту же дату.
Мы можем сделать это, используя несколько CTE, но я уверен, что есть лучший способ (возможно, с использованием некоторой функции типа row_number?). Какие-либо предложения? Что мне действительно не нравится в нашем решении, так это то, что оно абсолютно негибкое (что происходит, когда они хотят увидеть встречу THIRD в заданном диапазоне дат и т. Д.).
Во всяком случае; вот что мы придумали:
declare @startDate date = '2011-12-01'
declare @endDate date = '2011-12-31'
;
-- Limit to appointments before the end date
with AppointmentDates as (
select
AppointmentId,
CustomerId,
AppointmentDate
from
Appointment
where
AppointmentDate < @endDate
),
-- Get first appointment date - careful to cater for customers who have had
-- two appointments on the same day
FirstAppointments as (
select
CustomerId,
Min(AppointmentId) AppointmentId,
Min(AppointmentDate) AppointmentDate
from
AppointmentDates
group by
CustomerId
),
-- Second appointment date
SecondAppointments as (
select
AppointmentDates.CustomerId,
Min(AppointmentDates.AppointmentId) AppointmentId,
Min(AppointmentDates.AppointmentDate) AppointmentDate
from
AppointmentDates
inner join FirstAppointments on AppointmentDates.CustomerId = FirstAppointments.CustomerId
where
AppointmentDates.AppointmentId > FirstAppointments.AppointmentId
group by
AppointmentDates.CustomerId
having
Min(AppointmentDates.AppointmentDate) > @startDate
)
-- Bulk of query goes here; trimmed for brevity
select * from SecondAppointments