我需要按照SQL Server 2008中的以下详细信息获取结果

时间:2016-05-13 21:27:52

标签: sql sql-server sql-server-2008 tsql

enter image description here

我有两个相同列的不同表。一个是#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获取数据,其中In和out属于#temp2的In和Out之间。上述查询适用于绝对输入和输出。

考虑#temp1的第11项和#temp2的第1和第4项。 #temp1的输入和输出是从4月17日到4月20日,而#temp2中有两个这个日期范围的输入。一个是4月12日 - 4月18日,另一个是4月18日 - 4月20日。因此#temp1的结果应该分成以下两个条目。

  1. 4月17日 - 4月18日,#temp2。
  2. 的栏值为RoomId = 1
  3. 4月18日 - 4月20日,#temp2。
  4. 的栏值为RoomId = 2

    并且#temp1应该只有唯一的列。

3 个答案:

答案 0 :(得分: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。这是一个有趣的问题,如果你想要不同的东西,请回复。

答案 1 :(得分: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中{1}}中的1行中有超过2行不适合您。

答案 2 :(得分: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