Выберите последнюю запись с дополнительными условиями

ID    Level Effective Date  ExpirationDate
000012-12     2 12/01/2005  NULL
000012-12    1    12/01/2005  NULL
000012-12    2    12/01/2005  01/01/2009
000012-A12    2 10/01/1994  11/30/2005
000012-A12    2 01/01/1999  11/30/2005
000012-A12    2 09/01/2001  11/30/2005
000012-A12    1 12/01/2005  12/31/2007

Будут извлечены только самые последние записи. Это означает, что в приведенном выше сценарии
Exp date — если null, запись все еще активна.
Если больше, чем текущая отметка времени, ее будущая дата exp , что означает, что она все еще активна.
Если меньше, чем текущая отметка времени, затем прекращена.
Самая последняя — это самая активная или последняя прекращенная запись. Если он был активен и завершен, то будет отображаться только активный. Остальное последняя прекращенная запись.

Один идентификатор может иметь 2 строки для одной и той же даты вступления в силу и даты истечения срока действия, но нескольких уровней. Таким образом, в этом случае нам нужно будет выбрать только 1 запись для первого уровня.

Таким образом, в соответствии с приведенным выше набором данных ниже предполагаемый результат

Выход

000012-12    1   12/01/2005  NULL
000012-A12  2   12/01/2005  01/01/2009

Пожалуйста помоги

Томас. Пожалуйста, ознакомьтесь со следующим набором данных.

Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000872-A24',1,'1994-10-01',NULL); 
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000872-A24',1,'1999-01-01',NULL);  
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000872-A24',2,'2001-09-01',NULL ); 
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000872-A24',1,'2003-01-01','2007-12-31'); 

Когда вы запускаете запрос, он должен дать

000872-A24 2 01.09.2001 НОЛЬ

но теперь он возвращается

000872-A24 1 01/01/2003 12/31/2007


person user414610    schedule 09.08.2010    source источник
comment
@sqllearner190 – есть ли в таблице первичный ключ, такой как столбец auto_increment или идентификатор?   -  person Thomas    schedule 09.08.2010
comment
@ sqllearner190. Можете ли вы продемонстрировать в своем образце данных ситуацию, которая потребовала бы второго условия пункта № 2 в вашем списке требований?   -  person Thomas    schedule 09.08.2010
comment
Вот о чем я думал. Потому что, когда они запрашивают последнюю запись, она всегда должна давать 1 из множества ... и тогда это не будет зависеть от уровня ... Но все же, как мне выбрать самую последнюю запись (на основе даты истечения срока действия)   -  person user414610    schedule 09.08.2010
comment
@sqllearner190 — Нам нужно больше информации, чтобы дать разумный ответ. Опубликовали ответ, который ставит некоторые из этих вопросов.   -  person Thomas    schedule 09.08.2010
comment
Томас, я только что получил разъяснение по требованию. Ниже приведен идентификатор сценария. /1994 30.11.2005 000012-A12 2 01.01.1999 30.11.2005 000012-A12 2 01.09.2001 30.11.2005 000012-A12 1 01.12.2005 31.12.2007 нужно выбрать самую последнюю запись, которая будет на дату истечения срока действия. Я должен сделать это для всех идентификаторов   -  person user414610    schedule 09.08.2010
comment
@sqllearner - Пожалуйста, обновите свой исходный пост любой новой информацией.   -  person Thomas    schedule 09.08.2010


Ответы (1)


Трудно дать ответ, не зная продукта базы данных.

1. if there is no auto_increment/identity column 
2. and if there is no other primary key (which is a bad idea obviously) 
3. and if the given database product supports `CURRENT_TIMESTAMP` (each DBMS will likely have some equivalent to the current date and time) 
4. and if the target date by which you measure "latest" is the current date and time


Select Id, Level
From Table As T
Where T. EffectiveDate =    (
                            Select Max(T2.EffectiveDate)
                            From Table As T2
                            Where T2.ID = T.ID
                                And ( T2.EffectiveDate Is Null
                                    Or (
                                        CURRENT_TIMESTAMP >= T2.EffectiveDate
                                        And CURRENT_TIMESTAMP <= T2.ExpirationDate
                                        )
                                    )
                            )   

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

  1. Какой продукт базы данных и версия?
  2. Есть ли в таблице уникальный ключ auto_incrementing?
  3. Как Уровень вписывается в желаемые результаты? (Пожалуйста, расширьте свои образцы данных, чтобы включить крайние случаи).
  4. Что должно произойти, если текущая дата и время предшествуют дате вступления в силу с нулевой датой истечения срока действия?

ИЗМЕНИТЬ

Теперь, когда мы знаем, что вы используете SQL Server 2008, решение упрощается:

If object_id('tempdb..#Test') is not null
    Drop Table #Test;
GO
Create Table #Test (
                    PkCol int not null identity(1,1) Primary Key
                    , Id varchar(50) not null
                    , Level int not null
                    , EffectiveDate datetime not null
                    , ExpirationDate datetime null
                    );

Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000012-12',2,'12/01/2005',NULL);
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000012-12',1,'12/01/2005',NULL); 
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000012-12',2,'12/01/2005','01/01/2009');
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000012-A12',2,'10/01/1994','11/30/2005');
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000012-A12',2,'01/01/1999','11/30/2005');
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000012-A12',2,'09/01/2001','11/30/2005');
Insert #Test( Id, Level, EffectiveDate, ExpirationDate ) Values ('000012-A12',1,'12/01/2005','12/31/2007');

With Items As
    (
    Select PkCol, Id, Level, EffectiveDate, ExpirationDate
        , Row_Number() Over (   Partition By Id
                                Order By EffectiveDate Desc, Coalesce(ExpirationDate,'99991231') Desc, Level Asc ) As Num
    From #Test
    )
Select PkCol, Id, Level, EffectiveDate, ExpirationDate
From Items
Where Num = 1

В вашем образце вывода у вас есть комбинация ('000012-A12',2,'12/01/2005','01/01/2009'), которой нет в ваших исходных данных.

Я использую две функции, которые были добавлены в SQL Server 2005: общие табличные выражения и функции ранжирования. Выражение общей таблицы Item действует как представление на месте или запрос. В функции ранжирования Row_Number происходит настоящее волшебство. Как следует из названия, он возвращает последовательный список чисел, упорядоченных по предложению Order By. Однако он также перезапускает нумерацию для каждого значения идентификатора (это бит Partition By). Фильтруя по Num = 1, я возвращаю «верхнее» значение для каждого идентификатора.

person Thomas    schedule 09.08.2010
comment
Томас, я только что получил разъяснение по требованию. Ниже приведен идентификатор сценария. /1994 30.11.2005 000012-A12 2 01.01.1999 30.11.2005 000012-A12 2 01.09.2001 30.11.2005 000012-A12 1 01.12.2005 31.12.2007 нужно выбрать самую последнюю запись, которая будет на дату истечения срока действия. Я должен сделать это для всех идентификаторов в таблице - person user414610; 09.08.2010
comment
@sqllearner190- Вы должны обновить свой исходный пост с исправленными образцами данных. А как насчет других вопросов (версия базы данных, столбец auto_incrementing/identity, целевая дата, используемая для сравнения)? - person Thomas; 09.08.2010
comment
Томас, я обновил требование. Пожалуйста, помогите. В таблице также есть столбец идентификаторов. - person user414610; 09.08.2010
comment
вау... что ты наделал! Кажется, это очень продвинутый уровень программирования на SQL.. :-) .. Можете ли вы немного объяснить код.. - person user414610; 09.08.2010
comment
@Thomas - я обновил свой вопрос. Логика не работает для набора значений, которые я там указал. - person user414610; 09.08.2010
comment
Спасибо. Я просто изменил порядок следования предложений, и это сработало. Большое вам спасибо за вашу помощь . - person user414610; 09.08.2010