我有一个表存储一个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
我有一段时间来运行查询 即
StartDate : 30-JUN-2017
End date : 15-MAY-2018
我一直在寻找如下结果,表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 @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
答案 0 :(得分:1)
我相信我的结果接近我想要的结果,尽管不是
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 )