Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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
Sql server SQL Server-按给定日期拆分日期范围_Sql Server - Fatal编程技术网

Sql server SQL Server-按给定日期拆分日期范围

Sql server SQL Server-按给定日期拆分日期范围,sql-server,Sql Server,我有一个表,它存储一个Id和一个有效期,指示它何时处于活动状态 PortfolioId StartDate EndDate 1 2018-01-01 00:00:00.000 2018-05-31 00:00:00.000 2 2017-01-01 00:00:00.000 2018-05-31 00:00:00.000 我有另一个表,它存储了与上述Id相关的组件,并且也有一个有效期。对于表1中的任何给定条目,表2

我有一个表,它存储一个Id和一个有效期,指示它何时处于活动状态

PortfolioId StartDate                 EndDate
1           2018-01-01 00:00:00.000   2018-05-31 00:00:00.000
2           2017-01-01 00:00:00.000   2018-05-31 00:00:00.000
我有另一个表,它存储了与上述Id相关的组件,并且也有一个有效期。对于表1中的任何给定条目,表2可以有更多的条目

PortfolioComponentId    PortfolioId SplitDate
1                       1           2018-02-28 00:00:00.000
2                       1           2018-03-31 00:00:00.000

3                       2           2017-03-31 00:00:00.000
4                       2           2017-09-20 00:00:00.000
5                       2           2018-01-15 00:00:00.000
我有一段时间运行查询 i、 e

我一直在寻找下面这样的结果,其中表1中的数据是基于表2中的数据进行分割的

PortfolioId StartDate                 EndDate
1           2018-01-01 00:00:00.000   2018-02-28 00:00:00.000
1           2018-03-01 00:00:00.000   2018-03-31 00:00:00.000 - Starts from End date + 1 from the prev row
1           2018-04-01 00:00:00.000   2018-05-15 00:00:00.000

2           2017-06-30 00:00:00.000   2017-09-20 00:00:00.000 - Starts from Seach date [Portfolio component Id 3 ignored as it falls outside of search date range]
2           2017-09-21 00:00:00.000   2018-01-15 00:00:00.000
2           2018-01-16 00:00:00.000   2018-05-15 00:00:00.000 - Ends by seach end date
数据设置-如果有帮助

我相信我已经得到了接近我想要的结果,尽管不是
  • 最理想的方法
  • 从性能角度看的最佳方法
  • DECLARE@Temp表(BenchmarkDate-Datetime、ComponentType-int、PortfolioId-int)

    插入到@Temp中 从@Portfolio中选择StartDate、1、PortfolioId 联合 从@Portfolio中选择EndDate,2,PortfolioId

    插入到@Temp中 从@PortfolioComponents中选择SplitDate,2,PortfolioId 联合 从@PortfolioComponents中选择SplitDate+1,1,PortfolioId

    声明@Results表 ( Id INT标识(1,1), 开始日期时间, EndDate日期时间, 叶状体 )

    插入@Results 选择rset1.BenchmarkDate[Startdate], (选择最小值(rset2.基准日期) 来自@Temp rset2 其中rset2.ComponentType=2 和rset2.BenchmarkDate>rset1.BenchmarkDate 和rset1.PortfolioId=rset2.PortfolioId)[Enddate], rset1.叶状体 来自@Temp rset1

    其中rset1.ComponentType=1 按rset1.PortfolioId、rset1.BenchmarkDate排序

    挑选 当(@SearchStartDate介于StartDate和EndDate之间)然后@SearchStartDate ELSE StartDate END StartDate, 当(@SearchEndDate介于StartDate和EndDate之间)然后@SearchEndDate ELSE EndDate EndDate EndDate, 叶状体, ( 选择PortfolioComponentId 来自@PortfolioComponents pc 哪里 (pc.PortfolioID=r.PortfolioID和 (日期添加(d,1,pc.SplitDate)=r.StartDate) )PortfolioComponent 来自@Results r 哪里 (@SearchStartDateEndDate) 或 (@SearchEndDate介于StartDate和EndDate之间) 或 (@SearchStartDate介于StartDate和EndDate之间)

    PortfolioId StartDate                 EndDate
    1           2018-01-01 00:00:00.000   2018-02-28 00:00:00.000
    1           2018-03-01 00:00:00.000   2018-03-31 00:00:00.000 - Starts from End date + 1 from the prev row
    1           2018-04-01 00:00:00.000   2018-05-15 00:00:00.000
    
    2           2017-06-30 00:00:00.000   2017-09-20 00:00:00.000 - Starts from Seach date [Portfolio component Id 3 ignored as it falls outside of search date range]
    2           2017-09-21 00:00:00.000   2018-01-15 00:00:00.000
    2           2018-01-16 00:00:00.000   2018-05-15 00:00:00.000 - Ends by seach end date
    
    DECLARE @SearchStartDate DATETIME = '30-JUN-2017'
    DECLARE @SearchEndDate DATETIME = '15-MAY-2018'
    
    DECLARE @Portfolio TABLE
    (
        PortfolioId INT PRIMARY KEY IDENTITY(1,1),
        StartDate DATETIME,
        EndDate DATETIME
    )
    
    INSERT INTO @Portfolio
    SELECT '01-JAN-2018',  '31-MAY-2018'
    INSERT INTO @Portfolio
    SELECT '01-JAN-2017',  '31-MAY-2018'
    
    
    DECLARE @PortfolioComponents TABLE
    (
        PortfolioComponentId INT PRIMARY KEY IDENTITY(1,1),
        PortfolioId INT, 
        SplitDate DATETIME
    )
    INSERT INTO @PortfolioComponents
    SELECT 1, '28-FEB-2018'
    INSERT INTO @PortfolioComponents
    SELECT 1, '31-MAR-2018'
    
    INSERT INTO @PortfolioComponents
    SELECT 2, '31-MAR-2017'
    INSERT INTO @PortfolioComponents
    SELECT 2, '20-SEP-2017'
    INSERT INTO @PortfolioComponents
    SELECT 2, '15-JAN-2018'
    
    
    SELECT * from @Portfolio
    SELECT * from @PortfolioComponents
    
    DECLARE @Temp TABLE (BenchmarkDate Datetime, ComponentType int, PortfolioId INT)

    INSERT INTO @Temp SELECT StartDate , 1, PortfolioId FROM @Portfolio UNION SELECT EndDate , 2, PortfolioId FROM @Portfolio

    INSERT INTO @Temp SELECT SplitDate , 2, PortfolioId FROM @PortfolioComponents UNION SELECT SplitDate + 1 , 1, PortfolioId FROM @PortfolioComponents

    DECLARE @Results TABLE ( Id INT IDENTITY(1,1), StartDate DATETIME, EndDate DATETIME, PortfolioId INT )

    INSERT INTO @Results SELECT rset1.BenchmarkDate [Startdate], ( SELECT MIN(rset2.BenchmarkDate) FROM @Temp rset2 WHERE rset2.ComponentType = 2 AND rset2.BenchmarkDate > rset1.BenchmarkDate AND rset1.PortfolioId = rset2.PortfolioId) [Enddate], rset1.PortfolioId FROM @Temp rset1

    WHERE rset1.ComponentType = 1 ORDER BY rset1.PortfolioId, rset1.BenchmarkDate

    SELECT CASE WHEN (@SearchStartDate BETWEEN StartDate AND EndDate ) THEN @SearchStartDate ELSE StartDate END StartDate, CASE WHEN (@SearchEndDate BETWEEN StartDate AND EndDate) THEN @SearchEndDate ELSE EndDate END EndDate, PortfolioId , ( SELECT PortfolioComponentId FROM @PortfolioComponents pc WHERE (pc.PortfolioID = r.PortfolioId AND (DATEADD(d, 1, pc.SplitDate) = r.StartDate )) ) PortfolioComponentId FROM @Results r WHERE (@SearchStartDate < StartDate AND @SearchStartDate < EndDate AND @SearchEndDate > EndDate) OR (@SearchEndDate BETWEEN StartDate AND EndDate) OR (@SearchStartDate BETWEEN StartDate AND EndDate )