Список всех дат между двумя столбцами даты таблицы - PullRequest
2 голосов
/ 19 октября 2011

Моя таблица PRODUCT имеет 3 столбца:

Product_ID
INTRODUCED_DATE
WITHDRAWAL_DATE

Мне нужно создать производную таблицу PRODUCT_ALL_DATES из этой таблицы, в которой перечислены все даты, когда продукт был активен. Диапазоны дат: INTRODUCED_DATE (Дата начала) и WITHDRAWAL_DATE (Дата окончания)

Как этого добиться в SQL Server? Я указал пример вывода в прикрепленном изображении:

http://i.imgur.com/vOBVa.jpg

Спасибо!

Ответы [ 4 ]

5 голосов
/ 19 октября 2011
declare @dateh table(ind int identity(1,1),date1 smalldatetime,date2 smalldatetime)

insert into @dateh select '1/1/2011','1/15/2011'

select * from @dateh

;with T as
(
    select date1,date2 from @dateh as d
    union all
    select dateadd(dd,1,date1),date2 From T 
    where  dateadd(dd,1,date1)<= date2
)
Select date1 from T
1 голос
/ 19 октября 2011

Я могу придумать 2 способа достижения этого

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

Очевидный вопрос: почему вы хотите это сделать?что является проблемой, которая не может быть решена с данными в их текущем виде

0 голосов
/ 20 октября 2011

Вот ответ на ваш запрос, я попробовал это с помощью курсора.Работает нормально.

    CREATE TABLE product
(
product_id int
,INTRODUCED_DATE DATETIME
,WITHDRAWAL_DATE DATETIME
)

INSERT INTO product VALUES (100,'01-01-2011','01-05-2011')
INSERT INTO product VALUES (200,'05-30-2011','06-05-2011')

CREATE TABLE PRODUCT_ALL_DATES
(
product_id int
,Dates_Active DATETIME
)

DECLARE @product int
,@Introduct_Date DATETIME
,@Withdrawal_date DATETIME
,@Dates_Active DATETIME

DECLARE pointer_cur CURSOR FAST_FORWARD
FOR
SELECT * FROM product a

OPEN pointer_cur

FETCH NEXT FROM pointer_cur
INTO @Product,@Introduct_Date,@Withdrawal_date

WHILE(@@FETCH_STATUS=0)
BEGIN

    WHILE(@Introduct_Date<=@Withdrawal_date)
    BEGIN
        SET @Dates_Active=@Introduct_Date

        INSERT INTO PRODUCT_ALL_DATES
        SELECT @product,@Dates_Active

        SELECT @Introduct_Date=dateadd(day,1,@Introduct_Date)

    END

FETCH NEXT FROM POINTER_CUR
INTO @Product,@Introduct_Date,@Withdrawal_date

END

CLOSE POINTER_CUR
DEALLOCATE POINTER_CUR

SELECT * FROM PRODUCT_ALL_DATES 
0 голосов
/ 19 октября 2011

В зависимости от общего диапазона дат, это должно работать. Возможно, вам придется настроить рекурсию MAX, если у вас общий диапазон дат в целом.

;WITH DaysCTE( Date ) as
(
    SELECT MIN(INTRODUCED_DATE) AS Date FROM PRODUCT
        UNION ALL
    SELECT DATEADD(day, 1, Date) 
        FROM DaysCTE
        where Date < (SELECT MAX(@WITHDRAWAL_DATE) FROM PRODUCT)
)

SELECT
   PRODUCT_ID,
   DaysCTE.Date
FROM
   PRODUCT
INNER JOIN DaysCTE
 ON DaysCTE.Date >= PRODUCT.INTRODUCED_DATE
    AND DaysCTE.DATE <= PRODUCT.WITHDRAWAL_DATE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...