2016-05-13 25 views
1

enter image description here我需要得到的結果按以下細節在SQL Server 2008

我有相同的列的兩個不同的表。一個是#temp1,另一個是#temp2。

附加的圖像包含每個表的數據集。

我已經寫了一個查詢來獲取數據。下面是該查詢:

SELECT distinct A.EmpID, A.DeptIdID, A.RoomID, 
    IN= CASE WHEN DATEDIFF(S, A.IN, B.IN) >= 0 THEN B.IN ELSE A.In END, 
    Out= CASE WHEN DATEDIFF(S, A.Out, B.Out) >= 0 THEN A.Out ELSE B.Out END 

FROM #temp1 A 
INNER JOIN #temp2 B 
ON (A.In>= B.In AND A.In< B.In) 
    OR (A.Out> B.OutAND A.Out<= B.Out) 

我想是從#temp1中,其進出#TEMP2的In和Out之間屬於獲取數據。上面的查詢對於絕對進出入口來說工作得很好。

考慮#temp1的條目11和#temp2的條目1和4。 #temp1的In和Out條目是4月17日至20日,而#temp2中的這個日期範圍有兩個條目。一個是從4月12日到4月18日,另一個是從4月18日到4月20日。因此#temp1的結果應該分成以下兩個條目。

  1. 4月17日至4月18日與#temp2的列值RoomId = 1。
  2. 4月18日至4月20日,其中RoomId = 2來自#temp2的列值。

而且應該只有#temp1的唯一列。

+1

這是一個很好的開始。 http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/ –

+0

你的例子非常有限。例如,如果在另一個表的一個大範圍內有幾個較小的範圍,會發生什麼?如果有人真的想幫助你,你的數據應該是文本/插入子句/在sql小提琴中,而不必從圖片中寫入數據。 –

+0

可能是一個有趣的問題,但不清楚你想達到什麼或數據的含義。我認爲empid是獨一無二的。房間是由deptid + roomid唯一定義的嗎?兩個表格代表兩個部門中的房間deptid = 1和0以及誰預訂了他們以及他們使用的預訂日期?看起來JOIN條件不會像現在這樣返回任何行。 –

回答

0

我可能會誤解這個問題,但看起來好像你想找到任何在重疊日期預訂/使用過不同房間的員工。如果您連接#temp1#temp2到一個表#rooms,你可以運行這個命令:

SELECT * 
FROM #rooms A 
INNER JOIN #rooms B on a.empid = b.empid 
    and a.deptid * 10000 + a.roomid < b.deptid * 10000 + b.roomid 
where (A.indt <= B.outdt and A.outdt >= B.indt) 

我假設的房間被deptid & roomid標識。我使用快速而骯髒的黑客手段來生成一個整數,該整數唯一標識deptidroomid的組合,假設roomid始終小於10000

如果roomid唯一標識的房間,使用此:

SELECT * 
FROM #rooms A 
INNER JOIN #rooms B on a.empid = b.empid 
    and a.roomid < b.roomid 
where (A.indt <= B.outdt and A.outdt >= B.indt) 

a.roomid < b.roomid招消除重複。如果你說a.roomid <> b.roomid,那麼相同的重疊會被報告兩次,一次是從A的角度來看,另一次是從B的角度來看。

我還假設empid唯一標識該員工。由於員工可以在部門之間移動,因此員工ID往往是全公司範圍的。

HTH。這是一個有趣的問題,如果你想要一些不同的東西,請回復。

+0

我感謝您的努力和貢獻。有10000個額外的負載,這對我來說不起作用,因爲每張表中都有數萬億記錄。 – Avtansh

0

如果我理解你的權利,這將幫助:

SELECT a.EmpId, 
     a.DeptId, 
     a.RoomId, 
     CASE WHEN ROW_NUMBER() OVER (PARTITION BY a.EmpId ORDER BY a.[In]) = 1 THEN a.[In] ELSE b.[In] END as [In], 
     CASE WHEN ROW_NUMBER() OVER (PARTITION BY a.EmpId ORDER BY a.[In]) = 2 THEN a.[Out] ELSE b.[In] END as [Out] 
FROM #temp1 a 
INNER JOIN #temp2 b 
    ON b.[In] between a.[In] and a.[Out] and b.[Out] between a.[In] and a.[Out] 

輸出:

EmpId  DeptId  RoomId  In   Out 
----------- ----------- ----------- ---------- ---------- 
7637  1   1   2016-04-17 2016-04-18 
7637  1   1   2016-04-18 2016-04-20 
7638  1   1   2016-04-15 2016-04-18 
7638  1   1   2016-04-18 2016-04-20 
7639  1   1   2016-04-17 2016-04-18 
7639  1   1   2016-04-18 2016-04-20 

但如果在#temp2超過2行1列#temp1,不會對工作您。

+0

我感謝您的努力和貢獻。但是這對我不起作用,因爲#temp1中有多行,#temp1中有一行,反之亦然。 – Avtansh

0

我已經經歷了答案,我很感謝Stack Overflow開發人員社區的每位貢獻者的努力。

我應用了上述兩種方法,但在我的情況下沒有工作。

我從上週開始研究這個查詢,最後得到了我想要的。 這是我所做的。

SELECT 
    ROW_NUMBER() OVER (ORDER BY A.EmpID, A.In, A.Out) AS RowID, 
    A.EmpID, 
    IN= CASE WHEN DATEDIFF(S, A.In, B.In) >= 0 THEN B.In ELSE A.In END, 
    Out= CASE WHEN DATEDIFF(S, A.Out, B.Out) >= 0 THEN A.Out ELSE B.Out END, 
    CASE WHEN B.DeptID=1 THEN 1 ELSE 0 END AS IsAuthorized, 
    CASE WHEN (((A.In>= B.In AND A.In <= B.Out)) AND B.DeptID=1 AND A.DeptId=1) 
     THEN 1 ELSE 0 END AS IsAccessed 

    FROM #temp1 A 
    INNER JOIN #temp2 B 
    ON A.EmpID=B.EmpID 
    AND ((A.In>= B.In AND A.In < B.Out) 
      OR (A.Out > B.In AND A.Out <= B.Out)) 
    ORDER BY A.EmpID 

我再次感謝您的努力。

快樂編碼:)

謝謝!

Avtansh

相關問題