简体   繁体   中英

Compare datetime of two different tables and find not between columns

I have employee shift table, and then attendance table. I would like to know the shifts which the employee has not attended.

Below is the query to create sample tables.

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')

Below is my query to bring the shifts which employee not attended.

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

But it is returning every row. Can you help me achieve my requirement?

Expected output:

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

A big thanks in advance.

you may use this

   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  
            )

take care that you defined 1:30 not 13:30

Use this query:

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

I think you are looking for full overlaps between between the two tables. If so,the simplest approach is a LEFT JOIN or NOT 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;

Here is a rextester .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM