2016-01-21 34 views
1

我想要處理的查詢是計算hoursbilled。我想先檢查#worked,但是如果該表中不存在數據,我想從#workschedule中提取數據。總計只有一個實例

我的問題是它似乎總計我的數據兩次,即如果它存在於兩個表中它計數hoursbilled兩次。這對我的測試數據正常工作,但是當我將其轉出到生產數據時,會發生此問題。這是不正確的連接,還是錯誤的查詢設置?我需要做什麼才能獲得準確的計數hoursbilled

本質上講我的查詢試圖做的是:

  • 如果表中存在日期#worked使用hoursbilled從該表
  • 如果日期不存在,那麼hoursbilled#workschedule
  • 使用

Create Table #workschedule 
(
    caldate date 
    ,isworkday varchar(5) 
    ,hoursbilled int 
) 

Insert Into #workschedule Values 
('01/01/2000', 'yes','3'), ('01/02/2000', 'yes','3'), ('01/03/2000', 'yes','1'), 
('01/04/2000', 'no','0'), ('01/05/2000', 'yes','12'), ('01/06/2000', 'no','0') 

Create Table #worked 
(
    d1 date 
    ,hoursbilled int 
) 
Insert Into #worked Values 
('01/01/2000','2'), ('01/02/2000','4') 

Declare @begin date, @end date 
Set @begin = '01/01/2000' 
Set @end = '01/08/2000' 

Select 
ws.caldate, 
case when wk.d1 = ws.caldate then wk.hoursbilled else ws.hoursbilled end 
FROM #workschedule ws 
Left Join #worked wk 
ON ws.caldate = wk.d1 
where ws.isworkday = 'Yes' 
+0

你有它做兩次一個實際的例子?此外,您的案例陳述可以通過'COALESCE(wk.hoursbilled,ws.hoursbilled)' – ZLK

+0

@ZLK簡化 - 讓我從我的生產數據中構建一些臨時表格,然後編輯。我認爲Coalesce返回了第一個非空值,我從來沒有想過在這種情況下這樣做...... –

+0

它確實返回第一個非空值,但由於case語句的條件與您的條件相同加入,COALESCE在這裏工作得很好。 – ZLK

回答

0

@begin和@end根本不在您的查詢中使用。很少有問題可以幫助縮小問題的範圍:

。你有另一個謂詞來限制時間嗎? 。加入後您是否在caldate上聚合? 。你有#workschedule中的重複條目和#是否有相同的「caldate」?例如。無論您對#workschedule和#worked表的「caldate」是否有「唯一」約束?

這裏是潛在的原因,生產的雙數的例子:

/* 
create database test 

use test 

-- drop table #workschedule 
Create Table #workschedule 
(
    caldate date 
    ,isworkday varchar(5) 
    ,hoursbilled int 
) 

Insert Into #workschedule Values 
('01/01/2000', 'yes','3'), ('01/02/2000', 'yes','3'), ('01/03/2000', 'yes','1'), 
('01/04/2000', 'no','0'), ('01/05/2000', 'yes','12'), ('01/06/2000', 'no','0'), 
('01/01/2000', 'yes', '0') -- dup entry 

-- drop table #worked 
Create Table #worked 
(
    d1 date 
    ,hoursbilled int 
) 

Insert Into #worked Values 
('01/01/2000','2'), ('01/02/2000','4'), 
('01/01/2000', '5') -- dup entry 
*/ 

Declare @begin date, @end date 
Set @begin = '01/01/2000' 
Set @end = '01/08/2000' 

-- Here 2000/01/01 counted duplicated, should only account for 7, but got 14. 
--2000-01-01 14 
--2000-01-02 4 
--2000-01-03 1 
--2000-01-05 12 
Select 
    ws.caldate, 
    sum(
     case 
      when wk.d1 = ws.caldate then wk.hoursbilled 
      else ws.hoursbilled 
     end 
    ) hoursBilled 
FROM #workschedule ws 
    Left Join #worked wk 
     ON ws.caldate = wk.d1 
where 
    ws.isworkday = 'Yes' 
    and ws.caldate between @begin and @end 
group by ws.caldate 
order by ws.caldate 
相關問題