我的表格 PRODUCT
有3列:
Product_ID
INTRODUCED_DATE
WITHDRAWAL_DATE
我需要从这个表格中创建一个派生表PRODUCT_ALL_DATES
,列出产品活动的所有日期。日期范围是INTRODUCED_DATE
(开始日期)和WITHDRAWAL_DATE
(结束日期)。
我该如何在SQL Server中实现呢? 我已经在附图中标示了样本输出:
谢谢!
我的表格 PRODUCT
有3列:
Product_ID
INTRODUCED_DATE
WITHDRAWAL_DATE
我需要从这个表格中创建一个派生表PRODUCT_ALL_DATES
,列出产品活动的所有日期。日期范围是INTRODUCED_DATE
(开始日期)和WITHDRAWAL_DATE
(结束日期)。
我该如何在SQL Server中实现呢? 我已经在附图中标示了样本输出:
谢谢!
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
这是您查询的答案,我尝试使用游标来实现,它可以正常工作。
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
我可以想到两种方法来实现这个目标
显而易见的问题是,为什么你想要这样做?数据以其当前形式存在时无法解决的问题是什么?
根据日期的总范围,这应该可以工作。如果您有大量的日期范围,则可能需要调整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