2016-08-03 86 views
0

我有一個使用計數表插入指定月份的缺失行的查詢。該查詢測試一個月是否缺少一天,然後從列中獲取不同的值(在該月),並將這些值和缺失的日期值插入表中。從不同的表中獲取價值並在不同的查詢中使用價值

該表用於監控工作人員的工作日期,時間以及他們工作的部分。問題是中的某一列如果工作人員移動部分,Distinct語句會爲該特定日期創建兩組行。

這是工作的是獲得意外的結果查詢,(@Zohar佩萊德幫助我做到這一點)

DECLARE @startdt DATETIME = '2016/6/1'; 
DECLARE @enddt DATETIME = '2016/7/1'; 
DECLARE @value nvarchar(50); 


DECLARE @T as TABLE 
(
    Staff_ID int, 
    [Date]  date, 
    [Year]  int, 
    Mon   int, 
    [Day]  int, 
    First_Name varchar(10), 
    Last_Name varchar(10), 
    Section  varchar(10), 
    Time_Worked datetime 
) 

INSERT INTO @T VALUES 
(1001, '2016-06-01', 2016, 6, 1, 'Bill', 'Price', 'Level 1', '2016-06-01 8:30:00.000'), 
(1001, '2016-06-02', 2016, 6, 2, 'Bill', 'Price', 'Level 1', '2016-06-02 8:30:00.000'), 
(1001, '2016-06-03', 2016, 6, 3, 'Bill', 'Price', 'Level 1', '2016-06-03 8:30:00.000'), 
(1001, '2016-06-04', 2016, 6, 4, 'Bill', 'Price', 'Level 1', '2016-06-04 8:30:00.000'), 
(1001, '2016-06-05', 2016, 6, 5, 'Bill', 'Price', 'Level 1', '2016-06-05 8:30:00.000'), 
(1001, '2016-06-06', 2016, 6, 6, 'Bill', 'Price', 'Level 1', '2016-06-06 8:30:00.000'), 
(1001, '2016-06-07', 2016, 6, 7, 'Bill', 'Price', 'Level 2', '2016-06-07 8:30:00.000'),-- Different section 
(1001, '2016-07-05', 2016, 7, 5, 'Bill', 'Price', 'Level 2', '2016-07-5 8:30:00.000'), 
(1002, '2016-06-01', 2016, 6, 1, 'Mary', 'Somers', 'Level 1', '2016-06-01 8:30:00.000'), 
(1002, '2016-06-05', 2016, 6, 5, 'Mary', 'Somers', 'Level 1', '2016-06-05 8:30:00.000'), 
(1002, '2016-06-08', 2016, 6, 8, 'Mary', 'Somers', 'Level 1', '2016-06-08 8:30:00.000'), 
(1003, '2016-06-03', 2016, 6, 3, 'Mark', 'Jones', 'Level 1', '2016-06-03 8:30:00.000'), 
(1003, '2016-06-04', 2016, 6, 4, 'Mark', 'Jones', 'Level 1', '2016-06-05 8:30:00.000') 

[email protected] = SELECT Section_Data FROM Staff_Manager.dbo.Staff_Data_TBL WHERE Staff_No = 1001 


SET NOCOUNT ON; 
          IF object_id('dbo.Tally') is not null drop table dbo.tally 

          SELECT TOP 30000 IDENTITY(int,1,1) as ID 
           INTO dbo.Tally FROM master.dbo.SysColumns 
           ALTER table dbo.Tally 
           add constraint PK_ID primary key clustered(ID) 
          ; WITH Calendar AS 
          (
           SELECT dateadd(DD, ID-1, @startdt) as [Date] 
            FROM dbo.Tally 
            WHERE dateadd(DD, ID-1, @startdt) < @enddt 
          ) 


          INSERT INTO @T(Staff_ID, [Date], [Year], Mon, [Day], First_Name, Last_Name, Section) 
          SELECT DISTINCT Staff_ID, C.[Date], Year(C.[Date]), MONTH(C.[Date]), DAY(C.[Date]), First_Name, Last_Name, Section 
          FROM @T T 
          CROSS APPLY 
          (
           SELECT Cal.[Date] 
           FROM Calendar Cal 
           WHERE MONTH(Cal.[Date]) = MONTH(T.[Date]) 
           AND YEAR(Cal.[Date]) = YEAR(T.[Date]) 
           AND NOT EXISTS 
           (
            SELECT 1 
            FROM @T T2 
            WHERE T.Staff_ID = T2.Staff_ID 
            AND T2.[Date] = Cal.[Date] 
           ) 
          ) C 

          SELECT Staff_ID, [Date], [Year], Mon, [Day], First_Name, Last_Name, Section, Time_Worked 
           FROM @T 
           ORDER BY Staff_ID, [Date] 

這是結果,正如你可以看到它會爲工作人員Bill Price兩天由於2016-06-08由於他將SectionLevel 1更改爲Level 2。因爲Distinct聲明將從Section列獲得兩個值。

(運行代碼,你會得到所有的結果,這只是展示一下我的意思是SNIPPIT。)

Staff_ID Date Year Mon Day First_Name Last_Name Section Time_Worked 
1001 2016-06-01 2016 6 1 Bill Price Level 1 2016-06-01 08:30:00.000 
1001 2016-06-02 2016 6 2 Bill Price Level 1 2016-06-02 08:30:00.000 
1001 2016-06-03 2016 6 3 Bill Price Level 1 2016-06-03 08:30:00.000 
1001 2016-06-04 2016 6 4 Bill Price Level 1 2016-06-04 08:30:00.000 
1001 2016-06-05 2016 6 5 Bill Price Level 1 2016-06-05 08:30:00.000 
1001 2016-06-06 2016 6 6 Bill Price Level 1 2016-06-06 08:30:00.000 
1001 2016-06-07 2016 6 7 Bill Price Level 2 2016-06-07 08:30:00.000 
1001 2016-06-08 2016 6 8 Bill Price Level 1 NULL 
1001 2016-06-08 2016 6 8 Bill Price Level 2 NULL 
1001 2016-06-09 2016 6 9 Bill Price Level 1 NULL 
1001 2016-06-09 2016 6 9 Bill Price Level 2 NULL 
1001 2016-06-10 2016 6 10 Bill Price Level 1 NULL 
1001 2016-06-10 2016 6 10 Bill Price Level 2 NULL 
1001 2016-06-11 2016 6 11 Bill Price Level 1 NULL 
1001 2016-06-11 2016 6 11 Bill Price Level 2 NULL 
1001 2016-06-12 2016 6 12 Bill Price Level 1 NULL 
1001 2016-06-12 2016 6 12 Bill Price Level 2 NULL 
1001 2016-06-13 2016 6 13 Bill Price Level 1 NULL 
1001 2016-06-13 2016 6 13 Bill Price Level 2 NULL 

所以我保存的工作人員目前部分中的另一表,看代碼下面。

DECLARE @value nvarchar(50); 

DECLARE @T3 as TABLE 
(
    Staff_ID int,  
    First_Name varchar(10), 
    Last_Name varchar(10), 
    Section  varchar(10) 

) 

INSERT INTO @T3 VALUES 
(1001, 'Bill', 'Price', 'Level 2'), 
(1002, 'Mary', 'Somers', 'Level 1'), 
(1003, 'Mark', 'Jones', 'Level 1') 


SELECT Section FROM @T3 WHERE Staff_ID = 1001 

結果如下,得到該職員的數據爲Section。現在

Level 2 

,如果我能得到這個值,並把它作爲在Section列,將解決我的問題的默認值。

此代碼顯然是不正確,但而不是獲取Section列的distinct值,替換與來自其他表@T3, 像這樣的東西的價值是價值,

@value = SELECT Section FROM @T3 WHERE Staff_ID = 1001 

再有值插入到新行中。

DECLARE @value nvarchar(50); 

@value = SELECT Section FROM @T3 WHERE Staff_ID = 1001 

INSERT INTO @T(Staff_ID, [Date], [Year], Mon, [Day], First_Name, Last_Name, Section) 
          SELECT DISTINCT Staff_ID, C.[Date], Year(C.[Date]), MONTH(C.[Date]), DAY(C.[Date]), First_Name, Last_Name, @value 
          FROM @T T 
          CROSS APPLY 
          (
           SELECT Cal.[Date] 
           FROM Calendar Cal 
           WHERE MONTH(Cal.[Date]) = MONTH(T.[Date]) 
           AND YEAR(Cal.[Date]) = YEAR(T.[Date]) 
           AND Section = @value 
           AND NOT EXISTS 
           (
            SELECT 1 
            FROM @T T2 
            WHERE T.Staff_ID = T2.Staff_ID 
            AND T2.[Date] = Cal.[Date] 
           ) 
          ) C 

任何幫助將不勝感激。

+0

一名員工會在一天多於一節的工作中工作嗎? – Squirrel

+0

@Squirrel,不,他們可能會在月中改變,就是這樣。 – KyloRen

+0

是否有任何你存儲員工變更部分的日期? – Squirrel

回答

1

看到內碼

; WITH Calendar AS 
(
     SELECT dateadd(DD, ID-1, @startdt) as [Date] 
     FROM dbo.Tally 
     WHERE dateadd(DD, ID-1, @startdt) < @enddt -- changed for better performance 
) 
INSERT INTO @T(Staff_ID, [Date], [Year], Mon, [Day], First_Name, Last_Name, Section) 
SELECT DISTINCT Staff_ID, C.[Date], Year(C.[Date]), MONTH(C.[Date]), DAY(C.[Date]), First_Name, Last_Name, S.Section -- changed to use S.Section 
FROM @T T 
    CROSS APPLY 
    (
     SELECT Cal.[Date] 
     FROM Calendar Cal    
     WHERE MONTH(Cal.[Date]) = MONTH(T.[Date]) 
     AND  YEAR(Cal.[Date]) = YEAR(T.[Date]) 
     AND  NOT EXISTS 
       (
        SELECT * 
        FROM @T T2 
        WHERE T.Staff_ID = T2.Staff_ID 
        AND  T2.[Date] = Cal.[Date] 
       ) 
    ) C 
    OUTER APPLY -- added to get last known section based on date 
    (
     SELECT TOP 1 Section 
     FROM @T x 
     WHERE x.Staff_ID = T.Staff_ID 
     AND x.Date  < C.Date 
     ORDER BY x.Date DESC 
    ) S 

意見,如果沒有任何記錄外發現APPLY和你要顯示的均流段,加入到@ T3,並從那裏

獲得部分
+0

你是個天才!讓我測試一下真實的數據庫,我會盡快回復你。 – KyloRen

+0

非常感謝您的幫助。一個問題,我沒有使用'加入',我會在哪裏以及如何實現它。爲了記錄,這個問題得到了回答,我只是想知道,供將來參考。 – KyloRen

+0

有幾種'join'類似'INNER JOIN','LEFT OUTER JOIN','RIGHT OUTER JOIN'。基本上你會使用'JOIN'將多個表連接在一起。最常見的是「INNER JOIN」。您可以搜索或拾取SQL上的任何書籍,以瞭解有關各種類型連接的更多信息 – Squirrel