SQL仅选择在特定日期之后而不是在特定日期之前发生的项目

时间:2018-09-05 15:08:00

标签: mysql

我在SQL中有一个表,其中包含人员的ID,代码和每个代码的输入日期。 表X:

PERSON_ID  CODE  ENTRY_DATE
1            A   2017-12-03
1            C   2016-01-13
1            C   2009-05-11
2            B   2007-03-25
2            F   2018-01-18
3            G   2003-04-09

还有另一个表,其中包含每个人的person_id和参考日期。 表Y:

PERSON_ID   REF_DATE
1          2015-07-18
2          2017-06-17
3          2002-10-06

我想要做的是为每个人从表X中选择行,其中代码发生在表Y的REF_DATE之后,但代码本身也未出现在REF_DATE之前。例如,对于人1,在2015-07-18之后发生的代码是A(2017-12-03)和第一个C(2016-01-13)。但是由于C也在2009-05-11的REF_DATE(2015-07-18)之前出现,因此不选择C。

这只是一个示例,实际的表具有数百万行和数千种不同的代码,因此我无法手动键入代码等。 在此示例中查询的预期结果应为:

PERSON_ID  CODE  ENTRY_DATE
1            A   2017-12-03
2            F   2018-01-18
3            G   2003-04-09

有什么想法要用SQL编写代码吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

首先,您将两个表都连接在一起,因此您拥有REF_DATE,然后对行进行过滤以仅获取REF_DATE之后的行,而且还要确保在该日期之前使用该代码不存在任何行。

SQL DEMO

SELECT X.`PERSON_ID`, X.`CODE`, X.`ENTRY_DATE`, Y.`REF_DATE`
FROM TableX X
JOIN TableY Y
  ON X.`PERSON_ID` = Y.`PERSON_ID`
WHERE   X.`ENTRY_DATE` > Y.`REF_DATE`
  AND  NOT EXISTS (SELECT 1 
                   FROM TableX 
                   WHERE TableX.`PERSON_ID` = X.`PERSON_ID`
                     AND TableX.`CODE`= X.`CODE`
                     AND TableX.`ENTRY_DATE` <  Y.`REF_DATE`
                  )

输出

| PERSON_ID | CODE |           ENTRY_DATE |             REF_DATE |
|-----------|------|----------------------|----------------------|
|         1 |    A | 2017-12-03T00:00:00Z | 2015-07-18T00:00:00Z |
|         2 |    F | 2018-01-18T00:00:00Z | 2017-06-17T00:00:00Z |
|         3 |    G | 2003-04-09T00:00:00Z | 2002-10-06T00:00:00Z |