2017-10-31 27 views
1

このSQLコードを使用して、週末と休日のない就業日をカウントしています。誕生日の 'B'とは異なるイベントタイプごとにsDateとeDateの間にあれば、誕生日の日付を差し引くことはできますか?イベントのSQL - 例外のある勤務日数の計算

SELECT 
    evt.[Name], 
    evt.[type], 
    evt.sDate, 
    evt.eDate, 
    DATEDIFF(DD, evt.sDate, evt.eDate) + 1 
    - (DATEDIFF(WK, evt.sDate, evt.eDate) * 2) 
    - CASE WHEN DATEPART(DW, evt.sDate) = 1 THEN 1 ELSE 0 END 
    + CASE WHEN DATEPART(DW, evt.eDate) = 1 THEN 1 ELSE 0 END 
    - (SELECT COUNT(*) FROM tblHolidays AS h WHERE h.Data BETWEEN evt.sDate AND evt.eDate) as date_diff 
    -- subtract birthday date if between sDate and eDate 
    FROM tblEvents AS evt 
    WHERE YEAR(sDate) = YEAR(getdate()) 
    AND MONTH(sDate) = 12 
    ORDER BY evt.[Name] 

表: 値はdate_diff

enter image description here よろしく、エリオ・フェルナンデス

+0

タグ、使用しているDBMSを。そのクエリは製品固有のものです。 – jarlh

+0

希望する出力の形式は何ですか? – kchason

+0

私は、テーブル 'date_diff_final'を追加するためにテーブルを置き換えました。必要な列名は明るい青色ですが、date_diff(実際)の値はdate_diff_final(誕生日なし)と等しくなければなりません。私は私が明確であることを願っています! –

答えて

0

left joincase式を使った:

select 
    evt.[Name], 
    evt.[type], 
    evt.sDate, 
    evt.eDate, 
    datediff(day, evt.sDate, evt.eDate) + 1 
    - (datediff(week, evt.sDate, evt.eDate) * 2) 
    - case when datepart(weekday, evt.sDate) = 1 then 1 else 0 end 
    + case when datepart(weekday, evt.eDate) = 1 then 1 else 0 end 
    - (select count(*) from tblHolidays as h where h.Data between evt.sDate and evt.eDate) as date_diff 
    -- subtract birthday date if between sDate and eDate 
    - case when b.sDate is not null then 1 else 0 end 
from tblEvents as evt 
    left join tblEvents as b 
    on evt.Name = b.Name -- Hopefully there is a better identifier than Name, like an EmpId 
    and evt.Type != 'B' 
    and b.Type = 'B' 
    and b.sDate >= evt.sDate 
    and b.sDate <= evt.eDate 
where --year(evt.sDate) = year(getdate()) 
    --and month(evt.sDate) = 12 
    /* instead of using functions, use an appropriate date range */ 
    evt.SDate >= '20171201' 
    and evt.SDate < '20180101' 
order by evt.[Name] 
+0

うまくいきます。ありがとう。 –

+0

@ElioFernandesお手伝いを! – SqlZim

0

あなたの「減算の代わりにCASEステートメントを使用しますから減算する必要がある場合は、列の誕生日を示していdate_diffカラム計算の一部として減算される1または0を戻すコメントです。

生年月日列があるかどうかはわかりませんが、チェックしたい条件が解決策の鍵ではないため、WHENブロック内でチェックする必要がある条件を置き換えてください計算に必要な1または0を入力します。あなたのSELECT句に埋め込まれたときに、その周りに括弧が必要になります

SELECT CASE 
WHEN evt.Type != 'B' 
AND CAST(CONCAT(month(birthdate), '/', day(birthdate), '/', year(getdate())) AS date) BETWEEN evt.sDate AND evt.eDate 
THEN 1 ELSE 0 END 

:あなたが可能な誕生日の列を持っている場合、それは次のようになります。ちょうどevt.Type列を参照

、それは単純に取得します。

SELECT 
    evt.[Name], 
    evt.[type], 
    evt.sDate, 
    evt.eDate, 
    DATEDIFF(DD, evt.sDate, evt.eDate) + 1 
    - (DATEDIFF(WK, evt.sDate, evt.eDate) * 2) 
    - CASE WHEN DATEPART(DW, evt.sDate) = 1 THEN 1 ELSE 0 END 
    + CASE WHEN DATEPART(DW, evt.eDate) = 1 THEN 1 ELSE 0 END 
    - (SELECT COUNT(*) FROM tblHolidays AS h WHERE h.Data BETWEEN evt.sDate AND evt.eDate) 
    - CASE WHEN evt.Type != 'B' THEN 1 ELSE 0 END as date_diff 
    FROM tblEvents AS evt 
    WHERE YEAR(sDate) = YEAR(getdate()) 
    AND MONTH(sDate) = 12 
    ORDER BY evt.[Name] 
+0

コードに表示されているとおり、誕生日の桁は存在しません。私はちょうど助けにそれを置いた(それが助けなかったら残念)。 –

+0

誕生日がない場合、誕生日がsDateとeDateの間にあると判断する方法はありますか? –

+0

@JohnMo 'type = B'の行を仮定しています – SqlZim

関連する問題