2014-01-29 2 views
0

Регистрация программы создает проблему в нашей системе. Когда клиент переводится из одного штата в другой, система также отключает клиента от своей программы и повторно зачисляет клиента в программу в тот же день.TSQL SELECT Предварительная регистрация Если

ЦЕЛЬ: В моем запросе должна быть указана первая дата регистрации «p_effdt» (до любого повторного зачисления). Но я не хочу MIN (p_effdt), потому что это может не отражать каких-либо фактических ошибок регистрации.

ПРИМЕР: Клиент Адам регистрируется 1.02.2013. 4/1/2013 он переключается на другой штат, чтобы наша система не регистрировала и переписывала Адама 4/1/2013. Дата, которую я хочу сообщить для Адама, - 2/1/2013. Клиент Eve регистрируется 2/1/2013, а затем истекает 5/1/2013 и повторно регистрируется 7/1/2013. Дата, которую я хочу сообщить для Евы, - 7/1/2013.

SELECT client.c_id, c_ln + ', ' + c_fn AS 'Client', program.p_id, MIN(p_effdt) --that is wrong! 
FROM client INNER JOIN program ON client.c_id = program.c_id 
WHERE program.p_effdt BETWEEN '01.01.2013' AND '12.31.2013' 
AND program.p_id = '1234' 
GROUP BY client.c_id, c_ln, c_fn, program.p_id, p_effdt 
ORDER BY client.c_id  

Логика будет что-то вроде: если p_lpsdt = p_effdt затем перейти к предварительному p_effdt и спросить, если p_lpsdt = p_effdt снова ... Нужно ли что в SELECT, или использовать ROWCOUNT() или ...?

Благодарим за помощь.

+0

Я просто попробовал следующее, и это может сработать, я проверю его сейчас. Но все еще хочется услышать ваши мысли. Благодарю. , (SELECT MAX (p_effdt) WHERE p_effdt <> p_lapdt) – PowderSnorkel

+0

Теперь я пытаюсь: WHERE \t ((program.p_effdt BETWEEN '01 .01.2013 'AND '12 .31.2013') AND ((p_effdt <> p_lapdt) ИЛИ p_lapdt IS NULL)) – PowderSnorkel

+0

Я не уверен в терминологии. Может ли клиент регистрироваться, повторно регистрироваться (переключаться), а затем истекать? Если это так, я думаю, что вы получите их повторную регистрацию, а не их первоначальную регистрацию. – Zec

ответ

0

На самом деле, PowderSnorkel, я думаю, что вы, возможно, отклонили предложение BateTech преждевременно.

Теперь я не совсем уверен в вашей группе, и Jayvee прав, поскольку схема и некоторые тестовые данные могут помочь нам помочь (SQLFiddle отлично подходит для макетов), но если вы объедините предложение BateTech с вашим собственные критерии, он будет работать примерно так.

SELECT 
    client.c_id, 
    c_ln + ', ' + c_fn AS 'Client', 
    program.p_id, 
    MIN(p_effdt) 
FROM 
    client INNER JOIN program 
    ON client.c_id = program.c_id 
WHERE 
    program.p_effdt BETWEEN '01.01.2013' AND '12.31.2013' 
    AND program.p_id = '1234' 
    AND program.p_effdt > (
    SELECT 
     ISNULL(MAX(p2.p_lpsdt), '1900/01/01') 
    FROM 
     program p2 
    WHERE 
     p2.p_id = program.p_id 
     AND p2.c_id = client.c_id) 
GROUP BY 
    client.c_id, 
    c_ln, 
    c_fn, 
    program.p_id 
ORDER BY 
    client.c_id 

В ИНЕКЕ, мы являемся) с просьбой даты вступления в силу/с записями программ, которые старше, чем последний промежуток (если это применимо) и б) не являются, сами по себе, промахи. Сохранение MIN в предложении select должно гарантировать, что мы получим самую раннюю из них, которая обрабатывает случаи, когда клиент переключается, но не позволяет исходному/предыдущему зачислению. Я не уверен, что это действительный случай (вы никогда не отвечали на мой вопрос), но это, вероятно, стоит обработать.

Сообщите нам, если это приблизит вас.

+0

Привет, Zec, я получаю пустой набор (никаких строк не возвращаются). Во-первых, позвольте мне проследить вашу логику: выберите самую раннюю дату регистрации, которая после последней даты истечения срока (или после 1900/01/01, если null), где даты регистрации и окончания не совпадают. Это звучит хорошо, но я не уверен, почему это вернет пустой набор? hmmm ... – PowderSnorkel

+0

Я предполагаю, что p_lapsdt является NULL, когда не является записью lapse, поэтому 'p_effdt <> p_lapsdt' приведет к исключению записей, которые не являются исключениями (b/c выражение' @Any_date_value <> NULL' always возвращает false, думает об этом, поскольку чтение 'any_date_value не равно некоторому Неизвестному значению даты'). Это также приведет к исключению любых задержек, если p_lapsdt всегда равно p_effdt для записей с ошибками. Трудно сказать без выборочных данных, структуры таблицы и ожидаемых значений для данного сценария. Посмотрите, работает ли ответ, который я только что опубликовал. Существует ссылка на SQLFiddle w/test data и results. – BateTech

+0

Да, я даже предполагал, что дата истечения срока может быть NULL. Я не думаю, что есть причина проверить неравенство между датами в любом случае из-за того, что возвращаемые записи программы новее, чем самые последние. – Zec

1

Вот измененный запрос. Предполагая, что требуется «получить первую (минимальную) дату регистрации ПОСЛЕ последней (максимальной) даты пропадания по клиенту и идентификатору программы», тогда это должно сработать. Просмотрите этот SQLFiddle (http://sqlfiddle.com/#!3/8dd02/2) для получения результатов и образцов данных с 3 тестовыми примерами.

SELECT c.c_id, c_ln + ', ' + c_fn AS 'Client', p.p_id, MIN(p_effdt) as p_EffDt 
FROM #client c INNER JOIN #program p ON c.c_id = p.c_id 
WHERE p.p_effdt BETWEEN '01.01.2013' AND '12.31.2013' 
AND p.p_effdt > 
    ( select isnull(max(p2.p_lapsdt), '1900/01/01') 
     from #program p2 
     where p2.p_id = p.p_id and p2.c_id = c.c_id 
    ) 
--AND p.p_id = 1 --commented out to run for all clients 
GROUP BY c.c_id, c_ln, c_fn, p.p_id 
ORDER BY c.c_id 
Смежные вопросы