Sql检查1表中的日期是否在来自不同表的2个日期之间

时间:2017-01-03 11:34:31

标签: sql sql-server

我有2个sql表

  1. 具有Id,date,boolean value
  2. 有Id,日期
  3. 所以表1看起来像这样

        1 3/1/2017 false
        2 3/1/2017 true
        1 1/1/2017 false
        2 10/12/2016 false
    

    表2就像这样

        1 3/1/2017
        2 3/1/2017
        1 2/1/2017
        1 12/12/2016
    

    我想要的结果是表1中的每对日期具有相同的id并且彼此跟随例如id 1它是1/1/2017和3/1/2017 查找表2中是否有一个日期与这些日期之间的相同ID(包括当天),并且布尔值为false。

    所以例如在这种情况下的结果将是
    对于id1 2/1 / 2017,3 / 1/2017

    我该怎么做?

1 个答案:

答案 0 :(得分:2)

Table1中有多少行可以使用相同的ID?我假设2,但即使是1或3 +,查询也会合理地工作。

"互相追随" - 任何两个日期都会相互关联,除非它们是相同的,所以下面唯一真正的检查是不平等。

"布尔值为假" - 有两行,可以有不同的布尔值。我认为它们都必须是假的。 (false为0,true为1)

示例数据

这就是您的问题中应如何显示样本数据的方式。至少你应该以一种我们不必猜测月份和日期的方式来写日期。

DECLARE @Table1 TABLE (ID int, dt date, Flag bit);
INSERT INTO @Table1 (ID, dt, Flag) VALUES
(1, '2017-01-03', 'false'),
(2, '2017-01-03', 'true'),
(1, '2017-01-01', 'false'),
(2, '2016-12-10', 'false');

DECLARE @Table2 TABLE (ID int, dt date);
INSERT INTO @Table2 (ID, dt) VALUES
(1, '2017-01-03'),
(2, '2017-01-03'),
(1, '2017-01-02'),
(1, '2016-12-12');

<强>查询

WITH
CTE
AS
(
    SELECT
        ID
        ,MIN(dt) AS StartDT
        ,MAX(dt) AS EndDT
        ,MAX(CAST(Flag AS int)) AS MaxFlag
    FROM @Table1 AS Table1
    GROUP BY ID
)
SELECT
    CTE.ID
    ,A.dt
FROM
    CTE
    CROSS APPLY
    (
        SELECT
            Table2.dt
        FROM @Table2 AS Table2
        WHERE
            Table2.ID = CTE.ID
            AND Table2.dt >= CTE.StartDT
            AND Table2.dt <= CTE.EndDT
    ) AS A
WHERE
    StartDT < EndDT -- "are following each other"
    AND MaxFlag = 0 -- "the boolean is false" for both IDs
;

<强>结果

+----+------------+
| ID |     dt     |
+----+------------+
|  1 | 2017-01-02 |
|  1 | 2017-01-03 |
+----+------------+

Table2 (ID, dt)上的索引会有很大帮助。