2017-09-25 3 views
0

次の表があります。カナダの日は7月1日で、私のデータソースは営業日のみです。 7月1日が私のソーステーブルであるTABLE_A(名前:conm)にはないことに注意してください。SQL Server:すべての暦日の営業日

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 
+2

は本当に便利ではありません。私たちは、私たちの答えをテストするためにいくつかのクエリを実行する必要があり、私たちは写真でそれを行うことはできません。ここから始めましょう。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+1

質問を編集して[**サンプルデータ**]を追加してくださいhttp://plaintexttools.github.io/plain-text-table/)と、そのデータに基づく予想される出力。それらを[** Formatted text **](http://stackoverflow.com/help/formatting)と厳密に[** no screen shots **](http://meta.stackoverflow.com/questions/285551/)として提供するどうして私はアップロードできないのですか?コードのオン・ザ・イメージ・オン・ザ・ア・質問/ 285557#285557)。 **コメントにコードや追加情報を投稿しないでください。 [**最小限の、完全で検証可能な例**](https://stackoverflow.com/help/mcve)を持っていることを確認してください。 – SriniV

+0

あなたはこれまでに何を試しましたか? –

答えて

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 
0

これは、あなたが長いか短い範囲が必要な場合は、追加の「PASSを追加する必要があり長い場合だけ(コード内の日付を変更、2000年1月1日以来、あなたのすべての日付のテーブルを与えるだろう"CTEでは65kです。場合は、その後、LEFT JOINRIGHT 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()); 
関連する問題