2009-06-09 2 views
0

Вот проблема, которую я пытаюсь решить. У меня есть таблица, где я храню StartExclusionDate и EndExclusionDate и устанавливаю ApplyDate для моего объекта (это называется Исключение). В таблице может быть много записей ExtId.SQL-запрос поможет найти одиночную, отсортированную запись

Я хочу получить ApplyDate из последней непрерывной записи, где дата, переданная запросу, включена между StartExclusionDate и EndExclusionDate.

Так вот таблица я создал в SQL Server 2005:

Id int PK 
ExtId int FK 
StartExclusionDate datetime null 
EndExclusionDate datetime null 
ApplyDate not null 

А вот пример набора данных:

ID | ExtID | StartDate | EndDate | ApplyDate 
-------------------------------------------------------- 
    1  101  11/15/2005 3/15/2010 11/15/2005 
    2  101        12/30/2005 
    3  101  1/1/2000  1/1/2000  1/1/2006 
    4  101  4/1/2008     4/1/2008 
    5  101     8/1/2010  6/1/2008 
    6  101  11/1/2006 12/31/2010 11/1/2009 

Я проходил мимо 2 параметра, @ExtId и @dtDate. Запись, которую я хочу получить на основе следующих условий: @ExtId = 101, @dtDate = '6/15/2008' будет ID = 4

Логика такова:

  • Получить все записи для ExtId = 101 и где ApplyDate < = «6/15/2008' , сортировать ApplyDate DESC
  • Если первая запись в дату начала и окончания находятся между „6/15/2008“, найти запись, где исключение первоначально был установлен путем проверки на следующий записей

Я хотел найти способ сделать это без C URSOR, можно ли сделать запрос или CTE?

EDIT: Вот это делается с курсором

IF OBJECT_ID('TempDB..#t_edr','U') IS NOT NULL 
    DROP TABLE #t_edr 

CREATE TABLE #t_edr 
(
    Id INT NOT NULL, 
    ExtId INT NOT NULL, 
    StartDate DATETIME NULL, 
    EndDate DATETIME NULL, 
    ApplyDate DATETIME NOT NULL 
) 

DECLARE @ExtID INT, @dtDate DATETIME, @dtReturn DATETIME 
SELECT @ExtID = 101, @dtDate = '6/15/2008' 

SET NOCOUNT ON 
INSERT INTO #t_edr VALUES (1, 101, '11/15/2005', '3/15/2010', '11/15/2005') 
INSERT INTO #t_edr VALUES (2, 101, NULL, NULL, '12/30/2005') 
INSERT INTO #t_edr VALUES (3, 101, '1/1/2000', '1/1/2000', '1/1/2006') 
INSERT INTO #t_edr VALUES (4, 101, '4/1/2008', NULL, '4/1/2008') 
INSERT INTO #t_edr VALUES (5, 101, NULL, '8/1/2010', '6/1/2008') 
INSERT INTO #t_edr VALUES (6, 101, '11/1/2006', '12/31/2010', '6/1/2009') 
SET NOCOUNT OFF 

IF EXISTS (
    SELECT EDR.ID FROM #t_edr EDR 
    INNER JOIN (SELECT TOP 1 ID FROM #t_edr WHERE ExtId = @ExtID AND ApplyDate <= @dtDate ORDER BY ApplyDate DESC) LatestEDR 
    ON EDR.ID = LatestEDR.ID 
    WHERE ExtId = @ExtID 
    AND ApplyDate <= @dtDate  
    AND (StartDate IS NULL OR StartDate <= @dtDate) 
    AND (EndDate IS NULL OR EndDate >= @dtDate) 
    ) 
    BEGIN 
     DECLARE @ID INT, @StartEDR DATETIME, @EndEDR DATETIME, @ApplyDate DATETIME, 
      @CurrentApplyDate DATETIME, @Continue BIT 

     DECLARE c CURSOR LOCAL FAST_FORWARD FOR  
     SELECT Id, StartDate, EndDate, ApplyDate FROM #t_edr 
     WHERE ExtId = @ExtID AND ApplyDate <= @dtDate ORDER BY ApplyDate DESC 

     OPEN c 

     FETCH NEXT FROM c INTO @id, @startedr, @endedr, @ApplyDate 
     IF @@FETCH_STATUS <> 0 SET @Continue = 0 
     ELSE SET @Continue = 1 

     SET @CurrentApplyDate = @ApplyDate 
     WHILE @Continue = 1 
     BEGIN         
      IF @StartEDR >= @dtDate OR @EndEDR <= @dtDate 
       SET @Continue = 0 

      IF @Continue = 1 
      BEGIN 
       SET @CurrentApplyDate = @ApplyDate 
       FETCH NEXT FROM c INTO @id, @startedr, @endedr, @ApplyDate 
       IF @@FETCH_STATUS <> 0 SET @Continue = 0 
      END 
     END 
     CLOSE c 
     DEALLOCATE c 

     SELECT @CurrentApplyDate 
    END 
ELSE 
    PRINT 'NOT EXCLUDED' 

DROP TABLE #t_edr 

ответ

2
select top 1 * from table 
where ApplyDate <= '4/15/2008' 
and (startdate is null or startdate<= '4/15/2008') 
and (enddate is null or enddate >= '4/15/2008') 
and extid = '101' 
order by ApplyDate desc 
+0

Это будет возвращать первую запись (ID = 1), так как он соответствует StartDate и критерии EndDate –

+0

Вы правы, порядок должен опускаться. Проверьте это сейчас – tekBlues

+0

Этот запрос возвращает ID = 4. Я неправильно установил дату, которую нужно передать. Это должно быть «6/15/2008» вместо «4/15/2008» = ( Я обновил пример, извините за путаницу - уже был длинный день –

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