Исключая падение \ добавление в тот же день при сохранении реальной даты начала и окончания - PullRequest
1 голос
/ 11 февраля 2012

У нас есть таблица с обновлениями статуса для подписок на продукт. Запись начинается в таблице, когда начинается подписка, и эта запись обновляется с указанием даты окончания, когда заканчивается подписка. Одна из наших систем (не знаю, какая именно) иногда выполняет «отбрасывание \ добавление в тот же день», когда она заканчивает подписку, а затем начинает ее снова (создавая новую запись). Таким образом, один и тот же идентификатор подписчика прикрепляется к нескольким записям, хотя в действительности ничего не изменилось.

Пример данных будет таким:

recID subID   start           end        prodtype
1     19    01/11/2001  01/15/2001    A
2     19    01/15/2001  01/16/2001    A
3     19    01/16/2001  01/20/2001    A
4     19    01/30/2001  01/31/2001    A

Этот парень начал 1/11 и закончил 1/20. Записи 2 и 3 были введены системой (добавление в тот же день, но на самом деле это не так). Запись 4 - это еще одна подписка, которую г-н 19 начал позже.

У меня есть некоторый код, который будет пытаться разрешить только первую (реальную) запись каждой отдельной подписки, но он не может найти реальную дату окончания без использования max () и группировки по подписчику. Это, конечно, показало бы две подписки, 1/11 - 1/31 и 1/30 - 1/31, что неправильно.

Я рву свои волосы, пытаясь разрешить этот паттерн до двух таких записей:

subID   start           end        prodtype
 19    01/11/2001   01/20/2001    A
 19    01/30/2001   01/31/2001    A

Это в Teradata, но я считаю, что это просто ANSI SQL.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2012

Я считаю, что это ANSI SQL, но я тестировал его только на SQL Server.

По сути, запрос может находить истинные даты начала и истинные даты окончания независимо друг от друга. Затем, чтобы связать дату начала и даты окончания, связывают даты начала с датами окончания, которые превышают дату начала ..., а затем показывает наименьшую дату окончания.

SELECT
    startDates.subId,
    startDates.startDate,
    MIN(endDates.endDate) AS endDate,
    startDates.prodType
FROM
(
    SELECT
        recID, subID, startDate, prodType
    FROM yourTable s1
    WHERE NOT EXISTS (
        SELECT 1
        FROM yourTable s2
        WHERE 
            s1.startDate = s2.endDate
            AND s1.subId = s2.subId
    )
) startDates JOIN
(
    SELECT
        recID, subID, endDate, prodType
    FROM yourTable s1
    WHERE NOT EXISTS (
        SELECT 1
        FROM yourTable s2
        WHERE 
            s1.endDate = s2.startDate
            AND s1.subId = s2.subId
    )
) endDates ON
    startDates.subID = endDates.subID 
    AND startDates.startDate < endDates.endDate
GROUP BY
    startDates.subId,
    startDates.startDate,
    startDates.prodType

Вот запрос в действии ...

0 голосов
/ 11 февраля 2012

Вы можете найти все записи с фактическими датами окончания с таким кодом:

select t1.*
from myTable t1 left outer join myTable t2 on
t1.SubID = t2.SubID and  
t1.end = t2.start and t2.start is null

Конечно, вы можете найти стартовые записи аналогичным образом. Тогда, может быть, вы можете соединить их вместе.

При этом бывают случаи, когда нужно отказаться от выполнения всей обработки оператора select и использовать сохраненный процесс или вернуть все данные клиенту и обработать их там.

...