我需要根据 SQL Server 2008 中的以下详细信息获取结果
Posted
技术标签:
【中文标题】我需要根据 SQL Server 2008 中的以下详细信息获取结果【英文标题】:I need to get the result as per following details in SQL Server 2008 【发布时间】:2016-05-13 21:27:52 【问题描述】:我有两个相同列的不同表。一个是#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 的结果应该分成以下两个条目。
-
4 月 17 日 - 4 月 18 日,#temp2 的列值中 RoomId=1。
4 月 18 日至 4 月 20 日,RoomId=2,来自 #temp2 的列值。
#temp1 应该只有唯一的列。
【问题讨论】:
这是一个很好的起点。 spaghettidba.com/2015/04/24/… 您的示例非常有限。例如,如果另一个表的一个大范围内有几个较小的范围,应该怎么办?如果有人真的想帮助你,你的数据应该是文本/插入子句/在 sql fiddle 中,而不是必须从图片中写入数据。 可能是一个有趣的问题,但不清楚您想要实现什么或数据意味着什么。我认为 empid 是独一无二的。房间是由deptid + roomid唯一定义的吗?这两张表是否代表两个部门的房间 deptid = 1 和 0 以及谁预订了它们以及他们使用的预订日期?看起来 JOIN 条件不会返回任何行。 【参考方案1】:我可能误解了这个问题,但您似乎想查找在重叠日期预订/使用不同房间的任何员工。如果将#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
标识。我正在使用一种快速而肮脏的技巧来生成一个唯一标识deptid
和roomid
组合的整数,假设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。这是一个有趣的问题,如果您想要不同的东西,请回帖。
【讨论】:
感谢您的努力和贡献。由于每个表中有数万亿条记录,因此有 10000 的额外负载对我不起作用。【参考方案2】:如果我理解正确,这将有所帮助:
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 行以上,#temp1
中有 1 行,那将不适合您。
【讨论】:
感谢您的努力和贡献。但这对我不起作用,因为#temp2 中有多行,#temp1 中有 1 行,反之亦然。【参考方案3】:我已经阅读了答案,我感谢 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
【讨论】:
以上是关于我需要根据 SQL Server 2008 中的以下详细信息获取结果的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server Reporting Services 2008 中的列和行分组
基于 SQL server 2008 中的属性从大型数据库创建视图
SQL sever 2008 如何根据一个表中的两个时间计算出时间差
在 SQL Server 2008 R2 中为每个表创建创建触发器