2015-12-21 75 views
2

我有一個關於SQL Server的問題。SQL Server中的天差異

表:holidaylist

Date  | weekendStatus | Holidaystatus 
2015-12-01 | 0    | 0 
2015-12-02 | 0    | 0 
2015-12-03 | 0    | 0 
2015-12-04 | 1    | 0 
2015-12-05 | 1    | 0 
2015-12-06 | 0    | 1 
2015-12-07 | 0    | 0 
2015-12-08 | 0    | 0 
2015-12-09 | 0    | 1 
2015-12-10 | 0    | 0 
2015-12-11 | 0    | 0 
2015-12-12 | 1    | 1 
2015-12-13 | 1    | 0 

表:emp

empid | doj  | dos 
1  | 2015-12-01 | 2015-12-06 
2  |2015-12-01 | 2015-12-13 
3  |2015-12-03 |2015-12-13 

我想擺脫DOS的司法部天差withoutweekenstatusandholidaysstatus 和includeweekendandholidaystatus

我想這樣的輸出:

Empid | doj   | dos  |includeweekendandholidays | witoutincludeweekendandholidayslist 
1  | 2015-12-01 |2015-12-06 | 5      | 3  
2  | 2015-12-01 |2015-12-13 | 12      | 8 
3  | 2015-12-03 |2015-12-13 | 10      | 6 

我嘗試此查詢:

select 
    a.empid, a.doj, a.dos, 
    case 
     when b.weekendstatus = 1 and c.Holidaystatus = 1 
      then datediff(day, c.date, b.date) 
    end as includeweekenandholidays 
    case 
     when b.weekendstatus != 1 or c.Holidaystatus = 1 
      then datediff(day, c.date, b.date) 
    end as witoutincludeweekendandholidayslist 
from 
    emp a 
left join 
    holidaylist b on a.doj = b.date 
left join 
    holidaylist c on a.dos = c.date 

上面的查詢沒有給出預期的結果,請告訴我如何編寫查詢來實現SQL Server此任務

+2

這是什麼意思'withoutweekenstatusandholidaysstatus和includeweekendandholidaystatus'? –

+0

嘗試使用[日期] BETWEEN [doj]和[dos]加入您的表格一次。這會在開始日期和結束日期之間每天給你一行。你可以在WHERE子句中過濾掉你不想要的記錄。現在你將只有你想要的記錄,你可以計算。 –

+0

我們需要天差異b/w dos和doj爲每個empid和輸出需要包括wekenken和holidayststatusdays意味着多少天與wekenstatusandholidays一起工作,沒有weenkenstatusandholidaysstatus意味着需要找到他工作了多少天,沒有節假日和週末天和週末天找到holidayslist和weekendlist查看holidayslist table.please告訴我如何編寫查詢以在sql server中完成此任務 – ravi

回答

0

您可以使用OUTER APPLY

SELECT a.empid, a.doj, a.dos, 
     DATEDIFF(d, a.doj, a.dos) + 1 AS include, 
     DATEDIFF(d, a.doj, a.dos) + 1 - b.wd - b.hd + b.common AS without 
FROM emp AS a 
OUTER APPLY (
    SELECT SUM(weekendStatus) AS wd, 
     SUM(Holidaystatus) AS hd, 
     COUNT(CASE WHEN weekendStatus = 1 AND Holidaystatus = 1 THEN 1 END) AS common 
    FROM holidaylist 
    WHERE [Date] BETWEEN a.doj AND a.dos) AS b 

對於表emp的每一行,OUTER APPLY計算weekendStatus=1Holidaystatus=1行對應於此行的間隔。

選擇計算字段:

  • 包括emp間隔的天包括週末和節假日的總數。
  • 沒有是的emp間隔減去週末和節假日天的總數。 共同現場確保普通的週末假期不減兩次

注:上述查詢包括啓動並在計算所述間隔結束天,因此所考慮的時間間隔爲[DOJ - DOS]。您可以更改OUTER APPLY操作中的WHERE子句的謂詞,以排除間隔的開始日期,結束日期或兩者的天數。

Demo here

+0

嗨,您可以在不使用外部應用查詢的情況下提供該函數嗎?當我在update語句中使用相同的邏輯時時間outerapply需要更多的時間和它的查殺性能also.for邏輯明智給查詢工作fine.I需要備用查詢請提供它 – ravi

+0

@ravi我會建議嘗試傑米的答案。 –

0

您可以使用您帳戶中的一個CASE,以確定是否要的那一天算..

SELECT 
    e.empid, 
    e.doj, 
    e.dos, 
    COUNT(*) includeweekendandholidays, 
    COUNT(CASE WHEN Holidaystatus = 0 
        AND [weekendStatus] = 0 THEN 1 
      END) withoutincludeweekendandholidayslist 
FROM 
    emp e 
    JOIN holidaylist hl ON hl.Date >= e.doj 
          AND hl.Date < e.dos 
GROUP BY 
    e.empid, 
    e.doj, 
    e.dos 

,因爲它只連接來holidaylist你需要記錄表。這可能會表現得更好..

SELECT 
    e.empid, 
    e.doj, 
    e.dos, 
    DATEDIFF(DAY, e.doj, e.dos) includeweekendandholidays, 
    COUNT(*) withoutincludeweekendandholidayslist 
FROM 
    emp e 
    JOIN holidaylist hl ON hl.Date BETWEEN e.doj AND e.dos 
WHERE 
    weekendStatus = 0 
    AND Holidaystatus = 0 
GROUP BY 
    e.empid, 
    e.doj, 
    e.dos, 
    DATEDIFF(DAY, e.doj, e.dos) 

我沒有得到你的輸出,因爲它只顯示你不包括週末而不是假期..

1

試試這個:

select a.empid, 
     a.doj,a.dos, 
     IncludeRest = (select count(h.date) from holidaylist h where e.doj<=h.date AND e.dos>=h.date), 
     ExcludeRest = (select count(h.date) from holidaylist h where e.doj<=h.date AND e.dos>=h.date AND h.weekendstatus = 0 AND h.holdaystatus = 0) 
from emp e 
0

嘗試用交叉的另一種方式加入

select t.empid,t.doj,t.dos,datediff(day,t.doj,t.dos) includeweekendandholidays, 
datediff(day,t.doj,t.dos)-isnull(t1.wes,0) as witoutincludeweekendandholidayslist 
from @emp t left join (

select empid, sum(hd.Holidaystatus+hd.weekendStatus) wes from 
@emp emp cross join @holidaylist hd where hd.[Date] between doj 
and dateadd(day,-1,dos) group by empid) t1 on t.empid=t1.empid 

樣本數據

declare @holidaylist table ([Date] date, weekendStatus int, Holidaystatus int) 
insert into @holidaylist([Date], weekendStatus, Holidaystatus) values 
('2015-12-01' , 0    , 0), 
('2015-12-02' , 0    , 0), 
('2015-12-03' , 0    , 0), 
('2015-12-04' , 1    , 0), 
('2015-12-05' , 1    , 0), 
('2015-12-06' , 0    , 1), 
('2015-12-07' , 0    , 0), 
('2015-12-08' , 0    , 0), 
('2015-12-09' , 0    , 1), 
('2015-12-10' , 0    , 0), 
('2015-12-11' , 0    , 0), 
('2015-12-12' , 1    , 1), 
('2015-12-13' , 1    , 0) 

declare @emp table(empid int, doj date,  dos date) 
insert into @emp (empid,doj,dos) values 
(1  , '2015-12-01' , '2015-12-06'), 
(2  ,'2015-12-01' , '2015-12-13'), 
(3  ,'2015-12-03' ,'2015-12-13')