我需要根据 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 &amp; 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 &lt; b.roomid 技巧消除了重复。如果您说a.roomid &lt;&gt; 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 中为每个表创建创建触发器

根据 SQL Server 2008 R2 中特定列中的模式更改对行进行分组

SQL Server2008中的MERGE SQL语句中的MERGE的全称是什麼?代表什麼意思? 有没有