列出表的两个日期列之间的所有日期

发布于 2024-12-11 03:16:17 字数 405 浏览 0 评论 0原文

我的表 PRODUCT 有 3 列:

Product_ID
INTRODUCED_DATE
WITHDRAWAL_DATE

我需要从此表创建一个派生表 PRODUCT_ALL_DATES,其中列出了产品处于活动状态的所有日期。日期范围为 INTRODUCED_DATE(开始日期)和 WITHDRAWAL_DATE(结束日期)

如何在 SQL Server 中实现此目的?我已在附图中指出了示例输出:

https://i.sstatic.net/E05tr.jpg

谢谢!

My table PRODUCT has 3 columns:

Product_ID
INTRODUCED_DATE
WITHDRAWAL_DATE

I need to create a derived table PRODUCT_ALL_DATES from this table that list all the dates that a Product was active.The Date ranges are INTRODUCED_DATE (Start Date) and WITHDRAWAL_DATE (End Date)

How can I achieve this in SQL Server?I have indicated the sample output in the attached image:

https://i.sstatic.net/E05tr.jpg

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

巷子口的你 2024-12-18 03:16:17
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
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
贱人配狗天长地久 2024-12-18 03:16:17

我可以想到两种方法来实现此目的

  1. 编写一个存储过程并循环以填充第二个表
  2. 用另一种语言编写一个程序来执行此操作。

显而易见的问题是你为什么要这样做?以目前的数据形式无法解决的问题是什么

I can think of 2 ways to achieve this

  1. Write a stored procedure and loop throuh to populate the second table
  2. Write a program in another language to do it.

The obvious question is why do you want to do this? what is the problem that cannot be solved with data being in its current form

ゝ杯具 2024-12-18 03:16:17

这是您的查询的答案,
我用光标尝试过这个。它运行良好。

    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 

Here is the answer of your query,
i tried this by using Cursor. It is working fine.

    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 
情栀口红 2024-12-18 03:16:17

根据日期的总范围,这应该有效。如果总体日期范围较大,您可能需要调整 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

Depending on the total ranges of dates, this should work. You might need to adjust the MAX recursion if you have large range of dates overall.

;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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文