【问题标题】:MySQL Datediff - what is the issue?MySQL Datediff - 有什么问题?
【发布时间】:2019-01-15 13:58:27
【问题描述】:

我有以下问题。我的数据库如下所示:

Database structure

我想从这个数据库中获取所有超过 2 天的数据以及 status = "Betreiber informiert"status = "Betreiber informiert (manuell)"

我创建了一个查询,但它不工作。有人可以帮我吗?

这是我的查询:

SELECT * 
FROM meldungen 
WHERE status = 'Betreiber informiert' 
   OR status = 'Betreiber informiert(manuell)' 
  AND DATEDIFF(NOW(), Meldungszeitpunkt) > 172800

如果我使用这个查询,它看起来像这样:

Result with my query

您可以看到我的查询选择了所有具有status='Betreiber informiert''Betreiber informiert(manuell)' 但不考虑日期的行。

有人可以帮我吗?

【问题讨论】:

  • 当您混合 AND/OR 时,查询会变得混乱。具体逻辑最好用括号隔开。
  • 172800 应该代表什么?您的问题不清楚。
  • 计算天数秒
  • 请不要这样截图,转储SHOW CREATE TABLE tablename的建表结果

标签: php mysql sql datediff


【解决方案1】:

172800 是整整两天的数。如果你真的想这样做,那么你应该使用TIMESTAMPDIFF

SELECT m.*
FROM meldungen m
WHERE
    m.status IN ('Betreiber informiert', 'Betreiber informiert(manuell)') AND
    TIMESTAMPDIFF(SECOND, Meldungszeitpunkt, NOW()) > 172800;

请注意,我使用WHERE IN 来避免ORs 和ANDs 之间的操作顺序问题。 AND 的优先级高于 OR,因此您原来的 WHERE 子句实际上是这样评估的:

WHERE
    status = 'Betreiber informiert' OR
    (status = 'Betreiber informiert(manuell)' AND
     DATEDIFF(NOW(), Meldungszeitpunkt) > 172800)

【讨论】:

  • @user2864740 这是预期的逻辑 AFAIK。如果您有理由不相信,请出示一些证据。
  • 更新涵盖了“IN”开关——我唯一的问题是缺乏解释。
【解决方案2】:

嗯? 172800是什么?

试试这个:

SELECT m.*
FROM meldungen m
WHERE m.status IN ('Betreiber informiert', 'Betreiber informiert(manuell)') AND
      m.Meldungszeitpunkt < NOW() - interval 2 day;

请注意,这也简化了使用IN 的逻辑——因为我猜您希望将日期条件应用于两种状态。如果您真的只想将日期条件应用于第二个,那么您可以使用:

WHERE m.status = 'Betreiber informiert' OR
      (m.status = 'Betreiber informiert(manuell)') AND
       m.Meldungszeitpunkt < NOW() - interval 2 day
      )

这种解释对我来说似乎不太可能(尽管这是您的查询所做的)。

您可能需要curdate() 而不是now(),除非您想考虑时间。

【讨论】:

  • “嗯?什么是 172800?试试这个:” - 我希望一个非常低的代表成员给出这样的答案。 哈哈
  • @user2864740 。 . .那是因为明显的变化是日期比较。 IN 只是一个简化。
  • 这不是 Gordon 的失误……他的 SQL 级别相当高,所以像操作顺序这样微不足道的事情可能看起来并不值得注意(回答赞成)。
  • @TimBiegeleisen 我知道。但是这样看。如果这个答案来自新成员或低代表成员,你会怎么做?在收到很多反对票之前,我已经看到过这样的答案。现在说实话。
  • @FunkFortyNiner 。 . .老实说,我不知道 datediff() 的值 172800 与 2 天有什么关系。也许 OP 可以提供启发,尽管这对于获得正确的查询逻辑并不是必需的。
【解决方案3】:

我认为您只需将代码更改为以下内容:

SELECT * 
FROM meldungen 
WHERE status = 'Betreiber informiert' 
  AND DATEDIFF(NOW(), Meldungszeitpunkt) > 172800 
   OR status = 'Betreiber informiert(manuell)' 
  AND DATEDIFF(NOW(), Meldungszeitpunkt) > 172800

您必须为每个OR 编写AND 任务

使用您的旧代码,它只是从每个时间戳中搜索“Betreiber informiert”以及超过两天的“Betreiber informiert (manuell)”。

【讨论】:

  • 虽然这会改变逻辑(可能是也可能不是 OP 问题),但“(A 和 C)或(B 和 C)”可以更简单地写成“(A 或 B)和 C” 以避免重复。
  • 是的,你也可以这样做,但我喜欢将其结构化,以便我可以单独更改所有内容
猜你喜欢
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 2016-09-06
  • 2011-08-26
相关资源
最近更新 更多