Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
拆分表中的T-SQL日期范围,并将单个日期添加到表中_Sql_Sql Server_Tsql - Fatal编程技术网

拆分表中的T-SQL日期范围,并将单个日期添加到表中

拆分表中的T-SQL日期范围,并将单个日期添加到表中,sql,sql-server,tsql,Sql,Sql Server,Tsql,谢谢你的帮助。我有一张这样的桌子。让我们称之为TableA [Id] [CHAR](10) NOT NULL, [DType] [SMALLINT] NOT NULL, [PType] [CHAR](1) NOT NULL, [Period] [INT] NOT NULL, [FromDate] [SMALLDATETIME] NOT NULL, [ToDate] [SMALLDATETIME] NOT NULL, [Highval] [DECIMAL](19, 4) NULL, 主键是Id、

谢谢你的帮助。我有一张这样的桌子。让我们称之为TableA

[Id] [CHAR](10) NOT NULL,
[DType] [SMALLINT] NOT NULL,
[PType] [CHAR](1) NOT NULL,
[Period] [INT] NOT NULL,
[FromDate] [SMALLDATETIME] NOT NULL,
[ToDate] [SMALLDATETIME] NOT NULL,
[Highval] [DECIMAL](19, 4) NULL,
主键是Id、DType、PType、Period、FromDate

其中有如下数据:

Id          DType   PType   Period  FromDate    ToDate      Highval
-------------------------------------------------------------------    
000000000G  1       A       2015    2014-11-02  2014-11-04  0.4800
000000000G  1       A       2015    2014-11-01  2014-11-01  1.2860
000000000G  1       A       2015    2014-10-28  2014-10-31  1.2290
000000000K  4       2       2015    2014-12-17  2014-12-20  2.5800
000000000K  4       3       2015    2014-12-15  2014-12-16  2.1700
000000000K  4       3       2015    2014-11-14  2014-12-14  2.7200
我需要一种方法来拆分日期范围,任何大于或等于FromDate和小于或等于ToDate的内容,我需要将它们拆分为另一个名为IndividualDate的列,并放入同一个表中。基本上,在给定的日期范围内,如果日期介于FromDate和ToDate之间,则将日期写入另一个名为IndividualDate的列中。对于给定的Id,DType、PType、PEnd、FromDate、FromDate和ToDate字段日期范围没有重复项。因此,日期范围是完全分开的。最终输出表临时表很好,因为上面的示例数据如下所示

Id          DType   PType   Period  FromDate    ToDate      Highval IndividualDate
----------------------------------------------------------------------------------
000000000G  1       A       2015    2014-11-02  2014-11-04  0.4800  2014-11-02 
000000000G  1       A       2015    2014-11-02  2014-11-04  0.4800  2014-11-03 
000000000G  1       A       2015    2014-11-02  2014-11-04  0.4800  2014-11-04 
000000000G  1       A       2015    2014-11-01  2014-11-01  1.2860  2014-11-01 
000000000G  1       A       2015    2014-10-28  2014-10-31  1.2290  2014-10-28 
000000000G  1       A       2015    2014-10-28  2014-10-31  1.2290  2014-10-29 
000000000G  1       A       2015    2014-10-28  2014-10-31  1.2290  2014-10-30 
000000000G  1       A       2015    2014-10-28  2014-10-31  1.2290  2014-10-31 
000000000K  4       2       2015    2014-12-17  2014-12-20  2.5800  2014-12-17 
000000000K  4       2       2015    2014-12-17  2014-12-20  2.5800  2014-12-18 
000000000K  4       2       2015    2014-12-17  2014-12-20  2.5800  2014-12-19 
000000000K  4       2       2015    2014-12-17  2014-12-20  2.5800  2014-12-20 
000000000K  4       3       2015    2014-12-15  2014-12-16  2.1700  2014-12-15      
000000000K  4       3       2015    2014-12-15  2014-12-16  2.1700  2014-12-16 
000000000K  4       3       2015    2014-11-14  2014-12-14  2.7200  2014-12-14
如有任何建议,将不胜感激。提前感谢。

使用递归CTE生成日期

这个用的是理货台。供参考:


我还应该提到,最后一个表可能有几百万条记录。因此,它需要扩展。这将比递归CTE扩展得更好。请阅读以下内容以供参考:谢谢。由于时间限制,我用另一种方式解决了我遇到的问题,因此,我不必处理发布的问题。但是,我确实尝试过这个,它似乎起了作用。在发布问题之前,我确实尝试过使用递归CTE,但运气不太好。谢谢你的帮助!我将进一步研究这一点,以便更好地理解并在未来的工作中使用。再次感谢您的时间和解释。简直太棒了!感谢您抽出时间回答。我应该提到的是,我确实尝试过递归CTE,但没有走得太远。谢谢你的日历建议。我很感激在这方面所做的努力。非常感谢。
DECLARE @maxdate DATE

SELECT @maxdate = Max(todate)
FROM   Yourtable;

WITH cte
     AS (SELECT Min(fromdate) Invidualdate
         FROM   Yourtable 
         UNION ALL
         SELECT Dateadd(dd, 1, Invidualdate)
         FROM   cte
         WHERE  Invidualdate < @maxdate)
SELECT id,
       DType,
       PType,
       Period,
       FromDate,
       ToDate,
       Highval,
       Invidualdate
FROM   cte a
       JOIN Yourtable b
         ON a.Invidualdate BETWEEN b.FromDate AND b.ToDate 
Option (maxrecursion 0)
create table calender(Individualdate date)

insert into calender values('2001-01-01'),....,('2020-12-31')


SELECT id,
       DType,
       PType,
       Period,
       FromDate,
       ToDate,
       Highval,
       Individualdate
FROM   calender a
       JOIN yourtable b
         ON a.Individualdate BETWEEN b.FromDate AND b.ToDate 
;WITH e1(N) AS(
    SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL
    SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0 UNION ALL SELECT 0
)
,e2(N) AS(SELECT 0 FROM e1 a, e1 b)
,e4(N) AS(SELECT 0 FROM e2 a, e2 b)
,Tally(N) AS(
    SELECT TOP(SELECT MAX(DATEDIFF(DAY, FromDate, ToDate) + 1) FROM TableA) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM e4
)
SELECT
    a.Id,
    a.Dtype,
    a.Ptype,
    a.Period,
    FromDate = CONVERT(VARCHAR(10), a.FromDate, 120),
    ToDate = CONVERT(VARCHAR(10), a.ToDate, 120),
    IndividualDate = CONVERT(VARCHAR(10), DATEADD(DAY, t.N -1, a.FromDate), 120)
FROM TableA a
CROSS JOIN Tally t
WHERE   
    t.N - 1 <= DATEDIFF(DAY, a.FromDate, a.ToDate)
ORDER BY a.Id, a.DType, a.PType, a.Period, a.Highval, IndividualDate