【问题标题】:How to filter IDs based on dates?如何根据日期过滤 ID?
【发布时间】:2020-11-05 03:46:50
【问题描述】:

我有下表:

ID | DATES
---+-----------
1   02-09-2010
2   03-08-2011
1   08-01-2011
3   04-03-2010

我正在寻找至少有一个日期在 05-01-2010 之前和至少一个日期在 05-02-2010 之后的 ID

我尝试了以下方法:

WHERE tb1.DATES < '05-01-2010' AND tb1.DATES > '05-02-2010'

我不认为这是正确的,因为当我这样做时我没有得到正确的 ID,而且这个逻辑有问题。

有人可以解释我在这里做错了什么吗?

【问题讨论】:

  • 创建两个子查询,其中一个选择其日期之前的ID,另一个选择之后,然后intersect
  • 上述逻辑应该可行,但我认为逻辑上它是错误的。日期 2010 年 2 月 5 日。不会有任何日期匹配。

标签: sql-server ssms


【解决方案1】:

SQL 命令SELECT * FROM tb1 WHERE tb1.DATES &lt; '05-01-2010' AND tb1.DATES &gt; '05-02-2010' 要求“查找 'dates' 字段在 5 月 1 日之前和 5 月 2 日之后的所有行”,如果用英文输入,显然没有。

相反,该命令应该询问“查找所有记录在 5 月 1 日之前和另一条记录在 5 月 2 日之后的 ID”——这就需要查看每个 ID 的多条记录。

正如@Martheen 建议的那样,您可以使用两个(子)查询来做到这一点,例如,

SELECT A.ID
FROM
    (SELECT DISTINCT tb1.ID
      FROM mytable tb1
      WHERE tb1.[dates] < '20100501'
    ) AS A
INNER JOIN
    (SELECT DISTINCT tb1.ID
      FROM mytable tb1
      WHERE tb1.[dates] > '20100502'
    ) AS B
    ON A.ID = B.ID;

或使用 INTERSECT

SELECT DISTINCT tb1.ID
    FROM mytable tb1
    WHERE tb1.[dates] < '20100501'
INTERSECT
    SELECT mt2.ID
    FROM mytable mt2
    WHERE mt2.[dates] > '20100502';

在上面使用 DISTINCT 是为了让每个 ID 只获得一行,无论它们在相关日期之前/之后有多少行。

您也可以通过 GROUP BY 和 HAVING 来执行此操作 - 在这种特殊情况下很容易,就好像任何日期都在 5 月 1 日之前,那么它们的最早日期必须在 5 月 1 日之前(相应地,它们的最大数据和 5 月 2 日)例如,

SELECT mt1.ID
    FROM mytable mt1
    GROUP BY mt1.ID
    HAVING MIN(mt1.[dates]) < '20100501' AND MAX(mt1.[dates]) > '20100502';

这是一个db<>fiddle,其中包含所有 3 个;都提供相同的答案(一行,ID = 1)。

最后,您应该对日期使用明确 格式。我最喜欢的其中之一是没有破折号/斜线/等的“yyyyMMdd”(因为这些使它们模棱两可)。

不同的国家/服务器/等会以不同的方式转换您在那里的日期,例如SQL Server UTC string comparison not working

【讨论】:

    【解决方案2】:

    这是用于指定范围的一种解决方案。

    SELECT * from Table_name where
    From_date BETWEEN '2013-01-03'AND '2013-01-09'
    

    其他解决方案是你提到的,但看到逻辑是正确的

    SELECT * from Table_name where
    From_date > '2010-01-05'AND From_date <'2010-02-05'
    

    【讨论】:

    • 这是在做 OP 想要的,例如,“寻找至少有一个日期在 05-01-2010 之前和至少一个日期在 05-02-2010 之后的 ID”?
    • 其实在上面的例子中我只是选择了所有的列。如果要选择 ID,只需执行 SELECT ID from ... 选择 * 将有助于分析选择了哪些记录以及选择的记录是否正确。
    猜你喜欢
    • 1970-01-01
    • 2018-05-17
    • 2021-02-05
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多