比较两个不同表的日期时间,而不是在列

时间:2018-05-06 07:26:15

标签: sql sql-server

我有员工班次表,然后是考勤表。我想知道员工没有参加的班次。

以下是创建样本表的查询。

DECLARE @InsideOutsideTable TABLE 
(
    FromTime DATETIME,
    ToTime DATETIME
)

DECLARE @ShiftTable TABLE
(
    FromDateTime DATETIME,
    ToDateTime DATETIME
)

INSERT INTO @ShiftTable VALUES ('2018-05-02 07:30:00.000','2018-05-02 12:30:00.000')
INSERT INTO @ShiftTable VALUES ('2018-05-02 01:30:00.000','2018-05-02 16:30:00.000')

INSERT INTO @InsideOutsideTable VALUES ('2018-05-02 07:24:00.000','2018-05-02 11:47:00.000')
INSERT INTO @InsideOutsideTable VALUES ('2018-05-02 18:07:00.000','2018-05-02 18:32:00.000')

以下是我带来员工没有参加的轮班的查询。

SELECT
    S.*
FROM @ShiftTable S
CROSS APPLY @InsideOutsideTable T
WHERE S.FromDateTime NOT BETWEEN T.FromTime AND T.ToTime
AND S.ToDateTime NOT BETWEEN T.FromTime AND T.ToTime

但它正在回归每一行。你能帮我实现我的要求吗?

预期产出:

FromDateTime               ToDateTime
2018-05-02 01:30:00.000    2018-05-02 16:30:00.000

提前非常感谢。

3 个答案:

答案 0 :(得分:0)

你可以使用这个

   DECLARE @InsideOutsideTable TABLE 
(
    FromTime DATETIME,
    ToTime DATETIME
)

DECLARE @ShiftTable TABLE
(
    ID Int,
    FromDateTime DATETIME,
    ToDateTime DATETIME
)

INSERT INTO @ShiftTable VALUES (1,'2018-05-02 07:30:00.000','2018-05-02 12:30:00.000')
INSERT INTO @ShiftTable VALUES (2,'2018-05-02 13:30:00.000','2018-05-02 16:30:00.000')

INSERT INTO @InsideOutsideTable VALUES ('2018-05-02 07:24:00.000','2018-05-02 11:47:00.000')
INSERT INTO @InsideOutsideTable VALUES ('2018-05-02 18:07:00.000','2018-05-02 18:32:00.000')


SELECT S.*
FROM @ShiftTable S
WHERE ID NOT IN (
SELECT
    S.ID
FROM @ShiftTable S
INNER JOIN @InsideOutsideTable T
ON      (    ( T.FromTime <= S.ToDateTime  AND   T.FromTime >= S.FromDateTime )
                        OR ( T.ToTime <= S.ToDateTime  AND     T.ToTime >= S.FromDateTime )
                        OR ( T.FromTime <= S.FromDateTime AND T.ToTime >= S.ToDateTime )
                    )  
            AND     T.FromTime <= S.ToDateTime  
            )

注意您定义的是1:30而不是13:30

答案 1 :(得分:0)

使用此查询:

SELECT *
FROM
    (SELECT
        S.*,
        (SELECT 
             count(*)
         FROM @InsideOutsideTable T 
         WHERE T.FromTime BETWEEN S.FromDateTime AND S.ToDateTime
           OR T.ToTime BETWEEN S.FromDateTime AND S.ToDateTime) AS cnt
    FROM @ShiftTable S) AS tbl
WHERE cnt = 0

答案 2 :(得分:0)

我认为您正在寻找两个表之间的完全重叠。  如果是这样,最简单的方法是LEFT JOINNOT EXISTS

SELECT S.*
FROM @ShiftTable S LEFT JOIN
     @InsideOutsideTable T
     ON S.FromDateTime <= T.FromTime AND
        S.ToDateTime >= T.ToTime 
WHERE T.ToTime IS NULL;

这是rextester