2017-08-17 10 views
3

SQL Server 2008 R2を使用しています。SQL:日付のレコードが存在しない場合でも、連続するレコードの数。

私は、病院のアポイントメントスロットのテーブルを照会していて、特定の医者のアポイントメントスロットの数が、予約されているとフラグされ、週番号/年ごとにグループ化されたリストを返そうとしています。

まだ予約されている予定がない場合もありますが、予約された予定スロットの数がゼロの場合でも、今後のすべての週を一覧表示する必要があります。私は、標準の結果を集約する選択していることを理解し

------------------------------------------- 
Year | Week Number | Number of Booked Slots 
------------------------------------------- 
2017 |  48  |  10    
2017 |  49  |   0 
2017 |  50  |   4 
2017 |  51  |   2 
2017 |  52  |   0 
2018 |  1  |   5 

に何もないので、レコードのゼロカウントがありますそれらの週が表示されません。

私が探している出力は、これらの線に沿っています私はこれを回避しようとしましたが、最初にすべての今後の週のリストを作成しました。私は、私はゼロ週を表示するクエリを得ることができない可能性があるとして

しかし、私はこれに類似した問題の解決策の数を見て、しかし、実験Iの避難所」にもかかわらずき

...してみてください(SQL Count to include zero valuesを含む)

私がこれまでに書いた質問の最新の反復です。

WITH CTE_Dates AS 
    (
    SELECT DISTINCT Slot_Start_Date AS cte_date 
    FROM [Outpatients.vw_OP_Clinic_Slots WITH (NOLOCK) 
    ) 

SELECT 
    DATEPART(year,OPCS.Slot_Start_Date) [Year] 
    ,DATEPART(week,OPCS.Slot_Start_Date) [Week Number] 
    ,count(OPCS.Slot_Start_Date) [Number of Booked Slots] 

FROM 
    Outpatients.vw_OP_Clinic_Slots OPCS WITH (NOLOCK) 
    LEFT OUTER JOIN CTE_Dates ON OPCS.Slot_Start_Date=CTE_Dates.cte_date 
    LEFT OUTER JOIN Outpatients.vw_OP_Clinics CLIN ON OPCS.Clinic_Code=CLIN.Clinic_Code 

WHERE 
    OPCS.Slot_Start_Date >= '14/08/2017' 
    AND OPCS.Booked_Flag = 'Y' 
    AND CLIN.Lead_Healthcare_Professional_Name = 'Dr X' 

GROUP BY 
    DATEPART(year,OPCS.Slot_Start_Date) 
    ,DATEPART(week,OPCS.Slot_Start_Date) 

ORDER BY 
    DATEPART(year,OPCS.Slot_Start_Date)asc 
    ,DATEPART(week,OPCS.Slot_Start_Date)asc 

それは私に戻っていた結果は正しいですが、私はちょうどそれは、カウントがゼロのリストにそれらの数週間を含める必要があります。

誰かが間違っていると説明してください。私はcteに正しく参加していないと推測していますが、私は同じ結果を生み出す左右両方の結合を試みました。私はまた、上記のクエリステートメントとcteをスワップすることによってクエリを反転しようとしましたが、これはどちらも動作しません。

誰もが示唆しているガイダンスを理解してください。あなたが持っている結果セットに

答えて

1

だけRIGHT JOIN@ListOfWeeksテーブル:

DECLARE @ListOfWeeks TABLE ([Week_No] int, [Year_Number] int); 

DECLARE @i tinyint = 1, @y int = 2010; 

WHILE @i <= 52 AND @y < 2018 
BEGIN 
    INSERT INTO @ListOfWeeks([Week_No], [Year_Number]) VALUES (@i, @y); 

    IF @i = 52 BEGIN 
     SET @i = 0 
     SET @y +=1 
     END 
    SET @i += 1 
END 

SELECT * FROM @ListOfWeeks 

WITH [Your_Part] AS(
SELECT 
    DATEPART(year,OPCS.Slot_Start_Date) [Year] 
    ,DATEPART(week,OPCS.Slot_Start_Date) [Week Number] 
    ,count(OPCS.Slot_Start_Date) [Number of Booked Slots] 

FROM 
    Outpatients.vw_OP_Clinic_Slots OPCS WITH (NOLOCK) 
    LEFT OUTER JOIN CTE_Dates ON OPCS.Slot_Start_Date=CTE_Dates.cte_date 
    LEFT OUTER JOIN Outpatients.vw_OP_Clinics CLIN ON OPCS.Clinic_Code=CLIN.Clinic_Code 

WHERE 
    OPCS.Slot_Start_Date >= '14/08/2017' 
    AND OPCS.Booked_Flag = 'Y' 
    AND CLIN.Lead_Healthcare_Professional_Name = 'Dr X' 

GROUP BY 
    DATEPART(year,OPCS.Slot_Start_Date) 
    ,DATEPART(week,OPCS.Slot_Start_Date) 
), 
SELECT xxx.[Year_Number], xxx.[Week_No], yp.[Number of Booked Slots] 
FROM [Your_Part] yp 
RIGHT JOIN @ListOfWeeks xxx ON yp.[Year] = xxx.[Year_Number] AND yp.[Week Number] = xxx.[Week_No] 
+0

あなたの助け@Bartosz X.のためのおかげで、残念ながら、これは私のために働いていない - 私は、エラー 'オペランドのタイプを取得していますclash:dateはintと互換性がありませんおそらく私は結合構文が正しくないでしょうか?私は使用しました: 'Right JOIN @ListOfWeeks ON OPCS.Slot_Start_Date = Week_No'これは正しいですか? – Jon295087

+0

いいえ、week_numberに参加してください –

+0

申し訳ありません@Bartosz_X私はまだこの作業を行うことはできません。私はしようとしています: 'RIGHT JOIN @ListOfWEEks ON DATEPART(週、OPCS.Slot_Start_Date)= Week_No'しかし、それでも私はゼロ週なしで同じ結果を返します。私は[Week_Number]への参加を試みましたが、これはエラーを生成します: 'Week_Number'の近くに不正な構文があります.' [週番号]はエイリアス化された列なので参加できません。あなたの助けを感謝します - あなたが私の理解を助けるために具体的にできますか? – Jon295087

0
IF OBJECT_ID(N'tempdb..##cal_weeks_temp', N'U') IS NOT NULL 
DROP TABLE ##cal_weeks_temp; 
create table ##cal_weeks_temp (date_of_week date, week_num int) 
declare @start_date date 
declare @end_date date 
set @start_date='01/01/2017' 
set @end_date='12/31/2018' 
while @start_date<@end_date 
begin 
    set @start_date=dateadd(day,1,@start_date) 
    insert into ##cal_weeks_temp values (@start_date,DATEPART(week,@start_date)) 
end 
select YEAR(t1.date_of_week) 'YEAR',t1.week_num, 
sum(case convert(varchar,t2.BookedTime,105) when convert(varchar,t1.date_of_week,105) then 1 else 0 end) 'count' 
from ##cal_weeks_temp t1 
left join Your_Table t2 
on convert(varchar,t2.BookedTime,105)=convert(varchar,t1.date_of_week,105) 
group by YEAR(t1.date_of_week) ,t1.week_num 
order by YEAR(t1.date_of_week) ,t1.week_num 
+0

@ Javlon_Ismatov多くのご協力いただきありがとうございます。残念ながら、これは私にとってはうまくいきませんが、おそらくクエリを正しく適用していない可能性があります。 't2.BookedTime'は私の変数' Slot_Start_Date'を参照しています - それは正しいのですか?私はそれに応じて 'BookedTime'のすべてのインスタンスを修正し、クエリが実行されます。しかし、返される結果の数は正しくありません(ソースデータに対してクロスチェックしたとき)。また、予約数がゼロの週は表示されず、結果セットは週番号47で終了します(52週目まで表示されることを期待していました) – Jon295087

+0

私は自分のクエリを変更しました。恒久的な解決策のためには、暦年に新しいテーブルを作成する必要があります。パフォーマンス向上のために、日付、年、週番号などを含める必要があります。 –

関連する問題