提问者:小点点

在执行日期时间比较时,如何处理空值?


我的目标是计算出在特定时间我的网站上有多少账户。 我允许帐户在任何时候被取消,但如果他们在我查看的月份之后被取消,那么我仍然希望他们在快照上显示为活动状态。

我的帐户表,如下所示:

   --------------------------------------------------
        id                         | int
        signUpDate                 | varchar
        cancellationTriggeredDate  | datetime (NULLABLE)
   --------------------------------------------------

我编写了一个select语句来完成这个目标,如下所示:

SELECT
    COUNT(*) AS January_2020
FROM
    Accounts
WHERE
    STR_TO_DATE(signUpDate, '%d/%m/%Y') <= STR_TO_DATE('31/01/2020', '%d/%m/%Y')
    AND cancellationTriggeredDate <= '2020-01-31 00:00:00'

预期的结果将是3,这是我有多少帐户在一月份,并没有被取消后一月。 实际结果为0。 我相信这是因为不是所有我的帐户都有注销日期设置,但我不确定如何处理这件事。

为了更容易获得帮助,我创建了一个包含示例数据和模式的SQL Fiddle。

http://sqlfiddle.com/#!9/64 F3E3


共2个答案

匿名用户

您的日期比较需要正确的取消日期。

然后可以使用处理null:

SELECT COUNT(*) AS January_2020
FROM Accounts
WHERE STR_TO_DATE(signUpDate, '%d/%m/%Y') <= '2020-01-31' and
      (cancellationTriggeredDate > '2020-01-31' OR
       cancellationTriggeredDate IS NULL
      )

这是db<;>小提琴。 请注意,上面给出的是在2020-01-31 00:00:00(即一天开始时)处于活动状态的用户。 你可能指的是不同的事情:

  • 活动时间正好为2020-01-31 00:00:00的客户
  • 活动时间正好为2020-02-01 00:00:00的客户
  • 2020-01-31全天活动的客户
  • 2020-01整个月的活动客户
  • 在2020-01月份的任何时间活动的客户

所有这些都使用基本相同的逻辑,只是通过调整具体的比较。

匿名用户

替代解决方案-您可以在where谓词中使用case when,并使用假设较高的日期(即本世纪末)初始化CancellationTriggeredDate,然后在Where谓词中使用该字段进行比较。

SELECT
    COUNT(*) AS January_2020
FROM
    Accounts
WHERE
    STR_TO_DATE(signUpDate, '%d/%m/%Y') <= STR_TO_DATE('31/01/2020', '%d/%m/%Y')
    AND CASE WHEN cancellationTriggeredDate IS NULL THEN '2099-12-31' ELSE cancellationTriggeredDate END  > '2020-01-31 00:00:00'