【问题标题】:mysql DATE_FORMAT STR_TO_DATE date subquerymysql DATE_FORMAT STR_TO_DATE 日期子查询
【发布时间】:2014-06-28 03:11:25
【问题描述】:

这是RECORDS MySQL 表:

ID - BIGINT(20)
DATE - DATE

记录:

ID Date
1  2014-03-01
2  2014-03-02
3  2014-04-01
4  2014-04-02

这是第一个查询:

SELECT id, DATE_FORMAT(date,'%d/%m/%Y') AS date FROM records
WHERE
date >= STR_TO_DATE('01/04/2014','%d/%m/%Y') AND
date <= STR_TO_DATE('30/04/2014','%d/%m/%Y') 

一切正常,我得到了结果:

3,2014-04-01
4,2014-04-02

但是,当我尝试使用这样的子查询获取日期范围时:

SELECT * 
FROM (SELECT id, DATE_FORMAT(date,'%d/%m/%Y') AS date 
      FROM records) AS TEST
WHERE
date >= STR_TO_DATE('01/04/2014','%d/%m/%Y') AND
date <= STR_TO_DATE('30/04/2014','%d/%m/%Y') 

我得到一个空结果集(即零行)。

我的错误在哪里?

【问题讨论】:

  • 因为您的子查询和别名是外部查询中的日期字符串而不是日期。
  • 子查询中的“date”尝试“TEST.date”
  • 我试过:SELECT * FROM (SELECT id, DATE_FORMAT(date,'%d/%m/%Y') AS date FROM records) AS TEST WHERE TEST.date >= STR_TO_DATE(' 01/04/2014','%d/%m/%Y') AND TEST.date
  • @user3623185 在你的情况下,我会避免子查询。
  • @user3623185 尝试选择日期而不是选择 *

标签: php mysql date date-format str-to-date


【解决方案1】:

据我了解,您只想以%d/%m/%Y 格式返回日期。 我在您的问题中为您的第一个查询得到的结果实际上确实产生了这个转换后的日期,您确定这是您使用的查询吗?

无论哪种方式,如果这是您想要的,我相信您应该将查询更改为以下内容:

SELECT id, DATE_FORMAT(date,'%d/%m/%Y') AS datestring FROM records
WHERE
date >= STR_TO_DATE('01/04/2014','%d/%m/%Y') AND
date <= STR_TO_DATE('30/04/2014','%d/%m/%Y')

即使在比较中使用日期列而不是别名,我认为它可以澄清事情。

这是一个显示结果的SQLFiddle,您可以看到您的第一个查询正在返回所需的结果。

【讨论】:

  • 我也会这样做:简单而没有不必要的子查询 (+1)。
【解决方案2】:

DATE、DATETIME 和 TIMESTAMP 是自然有序的数据类型。也就是说,当您使用不等式和 BETWEEN 语句时,它们会执行您所期望的操作。

它们的默认文本表示——2014-05-07 11:59:56——在作为文本排序时也恰好是自然排序的。

但是当您执行 DATE_FORMAT(date,'%d/%m/%Y') 时,会将自然排序的表示转换为非自然排序的表示。

    03/15/2014  will sort before
    03/16/2013  

即使它不是,事实上,以前。

如果您想进行日期运算,则需要将日期保持在自然排序的形式中,直到它们真正显示出来。大多数人不会在 SQL 中使用 DATE_FORMAT() 将日期转换为可显示的格式;相反,他们使用 Java 或 PHP 程序进行显示。这样日期就保持自然顺序。

在您的问题中,您的外部查询无法判断它在日期之间进行。您已经告诉它在字符串上执行 BETWEEN,而这些字符串恰好不是自然排序的。

您在对@echo_Me 问题的评论中说您不希望在子查询中出现 BETWEEN。您要么必须将 DATE_FORMAT 放在外部查询中,要么将 BETWEEN 放在子查询中。

【讨论】:

    【解决方案3】:

    你必须在 TEST 中包含你的 where 子句。

      SELECT * 
     FROM (SELECT id, DATE_FORMAT(date,'%d/%m/%Y') AS date 
      FROM records
     WHERE
     date >= STR_TO_DATE('01/04/2014','%d/%m/%Y') AND
     date <= STR_TO_DATE('30/04/2014','%d/%m/%Y') 
       ) AS TEST
    

    但我不知道这里使用子查询的原因是什么?

    编辑:

    试试这个

     select * FROM(
     SELECT id, CASE WHEN date BETWEEN STR_TO_DATE('01/04/2014','%d/%m/%Y')
                               AND STR_TO_DATE('30/04/2014','%d/%m/%Y') 
                     THEN DATE_FORMAT(date,'%d/%m/%Y') 
                END AS date 
     FROM records
    ) as TEST
    WHERE //////  some other conditions
    

    【讨论】:

    • 我不希望它在子查询中,还有其他解决方案吗?
    • 我真的需要这样的东西:SELECT * FROM (SELECT id, DATE_FORMAT(date,'%d/%m/%Y') AS date FROM records) 作为测试这里的东西
    • SELECT * FROM (SELECT id, date FROM records) AS TEST WHERE date >= STR_TO_DATE('01/04/2014','%d/%m/%Y') AND date
    猜你喜欢
    • 2011-03-23
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 2021-12-29
    • 2014-03-28
    相关资源
    最近更新 更多