我有以下表格。由于加拿大日是7月1日,我的数据来源仅在工作日。请注意,TABLE_A(名称:conm
)缺少7月1日,这是我的源表。
CREATE TABLE [dbo].[comn]
(
CONM varchar(48),
valuedate datetime,
closeprice decimal(5,2)
)
GO
INSERT INTO comn VALUES ('SAPUTO INC', '2016-06-27', 37.66);
INSERT INTO comn VALUES ('SAPUTO INC', '2016-06-28', 38.34);
INSERT INTO comn VALUES ('SAPUTO INC', '2016-06-29', 38.48);
INSERT INTO comn VALUES ('SAPUTO INC', '2016-06-30', 38.37);
INSERT INTO comn VALUES ('SAPUTO INC', '2016-07-04', 38.12);
INSERT INTO comn VALUES ('SAPUTO INC', '2016-07-05', 38.59);
INSERT INTO comn VALUES ('SAPUTO INC', '2016-07-06', 38.75);
GO
我还有TABLE_B(businessdaysCAN
)加上所有加拿大假期。
CREATE TABLE [dbo].[businessdaysCAN]
(
valuedate datetime,
isholidayCA decimal(5,2)
)
GO
INSERT INTO businessdaysCAN VALUES ('2016-02-15',1);
INSERT INTO businessdaysCAN VALUES ('2016-03-25', 1);
INSERT INTO businessdaysCAN VALUES ('2016-05-23', 1);
INSERT INTO businessdaysCAN VALUES ('2016-07-01', 1);
INSERT INTO businessdaysCAN VALUES ('2016-08-01', 1);
INSERT INTO businessdaysCAN VALUES ('2016-09-05', 1);
INSERT INTO businessdaysCAN VALUES ('2016-10-10', 1);
GO
我想有一个输出表,例如加拿大假期时,我在最后一张桌子上的假期日期与前一天的价格一致。
CONM valuedate closeprice
------------------------------------------------
SAPUTO INC 2016-06-27 00:00:00.000 37.66
SAPUTO INC 2016-06-28 00:00:00.000 38.34
SAPUTO INC 2016-06-29 00:00:00.000 38.48
SAPUTO INC 2016-06-30 00:00:00.000 38.37
SAPUTO INC 2016-07-04 00:00:00.000 38.12
SAPUTO INC 2016-07-05 00:00:00.000 38.59
SAPUTO INC 2016-07-06 00:00:00.000 38.75
答案 0 :(得分:0)
这将为您提供自2000年1月1日以来所有日期的表格,如果您需要更长或更短的范围,只需更改代码中的日期(如果您需要更长时间,则可能需要添加额外的" PASS&# 34;在CTE但65k是很多天!);然后你可以LEFT JOIN
或RIGHT JOIN
到你的桌子并使用你的这里的值为null ...
WITH
_PASS0 AS (SELECT 1 AS Num UNION ALL SELECT 1), --2 ROWS
_PASS1 AS (SELECT 1 AS Num FROM _PASS0 AS A, _PASS0 AS B), --4 ROWS
_PASS2 AS (SELECT 1 AS Num FROM _PASS1 AS A, _PASS1 AS B), --16 ROWS
_PASS3 AS (SELECT 1 AS Num FROM _PASS2 AS A, _PASS2 AS B), --256 ROWS
_PASS4 AS (SELECT 1 AS Num FROM _PASS3 AS A, _PASS3 AS B), --65,536 ROWS
_TALLY AS (SELECT 0 AS Number UNION ALL SELECT ROW_NUMBER() OVER(ORDER BY Num) AS Number FROM _PASS4)
SELECT dateadd(DAY,Number,'20000101') AS CalendarDate
FROM _Tally
WHERE Number <= datediff(DAY,'20000101',getdate());
答案 1 :(得分:0)
你可以尝试一下
DECLARE @comn table (conm varchar(10) , valueDate date, closePrice decimal(10,2));
DECLARE @businessdaysCAN table(calDate date, isHolidayCA bit);
INSERT @comn (conm,valueDate,closePrice) VALUES
('SAPUTO INC','2016-06-27',37.66)
,('SAPUTO INC','2016-06-28',38.34)
,('SAPUTO INC','2016-06-29',38.48)
,('SAPUTO INC','2016-06-30',38.37)
,('SAPUTO INC','2016-07-04',38.12)
,('SAPUTO INC','2016-07-05',38.59)
,('SAPUTO INC','2016-07-06',38.75);
INSERT @businessdaysCAN (calDate, isHolidayCA) VALUES
('2016-05-23',1)
,('2016-07-01',1)
,('2016-08-01',1);
WITH
cteMinMaxDates as
(
select
conm
,Min(valueDate) as startdate
,Max(valueDate) as enddate
from @comn
Group by conm
),
cteAllDates
AS (SELECT conm
,startdate
,enddate
,valueDate = ( SELECT valueDate FROM @comn a where a.valueDate = t.startdate and a.conm = t.conm)
FROM cteMinMaxDates t
UNION ALL
SELECT conm
,Dateadd(day, 1, startdate) startdate
,enddate
,valueDate = CASE WHEN ( SELECT valueDate FROM @comn a where a.valueDate = startdate and a.conm = conm) IS NULL THEN valueDate ELSE ( SELECT valueDate FROM @comn a where a.valueDate = startdate and a.conm = conm) END
FROM cteAllDates
WHERE startdate < enddate)
SELECT
D.conm
,D.startdate valuedate
,IsNull(A.closePrice , B.closePrice) closePrice
FROM cteAllDates D
LEFT JOIN @comn A
ON D.conm = A.conm
AND D.startdate = A.valuedate
LEFT JOIN @comn B
ON D.valuedate = B.valuedate
WHERE A.valuedate IS NOT NULL
OR EXISTS (SELECT 1 FROM @businessdaysCAN c where d.startdate = c.calDate)
结果
conm valuedate closePrice
---------- ---------- ---------------------------------------
SAPUTO INC 2016-06-27 37.66
SAPUTO INC 2016-06-28 38.34
SAPUTO INC 2016-06-29 38.48
SAPUTO INC 2016-06-30 38.37
SAPUTO INC 2016-07-01 38.37
SAPUTO INC 2016-07-04 38.12
SAPUTO INC 2016-07-05 38.59
SAPUTO INC 2016-07-06 38.75
如果您需要该范围内的所有日期,请删除
WHERE A.valuedate IS NOT NULL
OR EXISTS (SELECT 1 FROM @table_b c where d.startdate = c.calDate)
结果
conm valuedate closePrice
---------- ---------- ---------------------------------------
SAPUTO INC 2016-06-27 37.66
SAPUTO INC 2016-06-28 38.34
SAPUTO INC 2016-06-29 38.48
SAPUTO INC 2016-06-30 38.37
SAPUTO INC 2016-07-01 38.37
SAPUTO INC 2016-07-02 38.37
SAPUTO INC 2016-07-03 38.37
SAPUTO INC 2016-07-04 38.12
SAPUTO INC 2016-07-05 38.59
SAPUTO INC 2016-07-06 38.75