2012-06-01 3 views
0

В Таблице приемлемости [ET] есть записи для подходящих [например] и неприемлемых [In]. Каждая запись имеет только одну дату, прикрепленную к ней. У меня есть службы клиентов [CS] в таблице служб [ST], что мне нужно определить, какой тип записей в последний раз предшествовал дате службы.запрос для последней действующей записи


______________ET______________ 



Eg 01.01.2012 
In 01.20.2012 
Eg 01.29.2012 
In 02.10.2012 

_________________________ST______________________________ 

CS Joe Schmoe 02.01.2012 11:00 AM 
CS Joe Schmoe 01.25.2012 1:00 PM 
CS Harold Doe 02.09.2012 4:00 PM 

Я хочу вернуть тот факт, что служба Джо чмо на 02.01.2012 11:00 AM имели право из-за записи правомочности на 01.01.2012, Джо чмо был неподходящим для услуги на 01.25.2012 1:00 вечера из-за записи о недействительности по состоянию на 01.20.2012, и Гарольд Шмоу имел право на услуги 02.09.2012 16:00 из-за записи о приемлемости в 01.29.2012.

__ _ __ _ __ _ __РЕЗУЛЬТАТЫ_ __ _ __ _ __ _ __ _ __ _ __

Джо чмо 02.01.2012 11:00 утра Приемлемые 01.01.2012
Джо чмо 01.25.2012 1:00 вечера Ineligible 01.20.2012
Harold Doe 02.09.2012 4:00 вечера Ineligible 01.29.2012

+0

Ваш пример результата и ваше описание, похоже, противоречат друг другу. – Mithrandir

+0

Так что, если я правильно понимаю, право на участие либо включено, либо выключено. Если дата службы находится в включенном периоде, она имеет право на участие. Если он находится в выключенном периоде, это не так. Это так? – mikeY

+0

Как ST присоединяется к ET? –

ответ

0

Предполагая, что единственное ограничение на UserId и дату в правомочности таблице (в противном случае, вам нужен другой тай-брейк, такие как добавление row_number через идентификатор пользователя, дата), вы:

  • РЕГИСТРИРУЙТЕСЬ ко всем записям, которые имеют дату меньше (дата CS)
  • Y ou затем возьмите максимум этих дат (так как вы хотите получить последнюю дату, предшествующую событию)
  • Затем вы присоединяетесь к исходной таблице, чтобы получить остальную часть информации о строках (тип состояния). Именно поэтому вам необходимо ограничение уникальности

SELECT 
    UserId, Date, Status, ETDate 
FROM (
    --The last matching status record by date 
    SELECT ST.UserId, ST.Date, MAX(ET.Date) as ETDate 
    FROM ST 
    JOIN ET ON 
     ST.UserId = ET.UserId 
     AND CS.Date >= ET.Date 
    GROUP BY 
     ST.UserId, ST.Date 
) as C 
JOIN ET as E ON 
    C.UserId = E.UserId 
    AND C.ETDate = E.ETDate 
+0

Нет таблицы CS и нет идентификатора пользователя в таблице ET. Могли бы вы пройти через это для тех из нас, кто, по-видимому, очень медленно? – mikeY

+0

@mikeY - Извините - s/CS/ST. Отсутствует информация о схеме, я предполагаю, что соединение должно быть на UserId. Если допустимое/Неподходящее является «глобальным» значением, должно быть достаточно простым, чтобы просто удалить UserId из соединения (и вам все равно потребуется уникальное ограничение на дату). –

0

Это кажется странным запроса, потому что elibility не на уровне пользователя.

Следующий запрос делает то, что вы хотите:

select et.*, st.elibility, st.ETDate 
from et cross join 
    (select st.* 
     from st join 
      (SELECT MAX(cs.Date) as lastcsDate 
      FROM st JOIN 
       et 
       ON st.Date <= et.Date 
      GROUP BY cs.UserId 
      ) t 
      on st.date = t.lastcsDate 
    ) lastst 

Примечание: Я не выполнить этот запрос, чтобы простить опечаток.

Это использует коррелированный подзапрос, чтобы получить самую последнюю дату или каждую дату в таблице et. Остальное просто соединяется в нужную информацию для предложения select.

2

Я сделал это так:

http://sqlfiddle.com/#!3/1c73b/5

select fname, etdate, 'eligible' as eligible 
from st 
where etdate between 
(select max(etdate) from et where status ='Eg') 
and 
(select max(etdate) from et where status ='In') 
union 
select fname, etdate, 'ineligible' as eligible 
from st 
where etdate not between 
(select max(etdate) from et where status ='Eg') 
and 
(select max(etdate) from et where status ='In') 
order by 2 
+0

Используйте UNION ALL, так как вы не будете обманывать. Также не уверен, что это правильно - вы просто смотрите на последние строки In/Eg. Если у вас был счет в 1/10/12, они были бы «неприемлемыми», хотя эффективная запись 1/10 была «приемлемой». –

2

apply был разработан для этого.

select 
    ST.fName, stETD = ST.etDate, previousET.* 
from 
    ST 
    outer apply (
     select top 1 
      ET.Status, 
      ET.ETDate 
     from 
      ET 
     where 
      ET.ETDate <= ST.etDate 
     order by 
      ET.ETDate desc 
    ) previousET 
order by 
    2 

http://sqlfiddle.com/#!3/1c73b/11

Это поможет вам в последнее время (order by ETDate desc) продолжающуюся запись (where ETDate <= ST.Date). Благодаря mikeY для скрипки.

+0

Это работает в моей скрипке, если вы очистите имена столбцов. Очень круто. – mikeY

+0

+1 для ясности, хотя обычно мне не нравятся коррелированные подзапросы (в основном это то, что применяется, –

Смежные вопросы