【问题标题】:Retrieve the values between two dates stored in dd/mm/yyy format (varchar)检索以 dd/mm/yyyy 格式存储的两个日期之间的值 (varchar)
【发布时间】:2012-04-06 14:06:25
【问题描述】:

我有一张这样的桌子:

   +-----+------------+
   | no  | Date       |
   +-----+------------+
   | 1   | 10/11/2011 |
   | 2   | 10/12/2011 |
   | 3   | 10/13/2011 |
   | 4   | 10/14/2011 |
   | 5   | 10/15/2011 |
   +-----+------------+

我编写了以下查询,但它没有返回任何内容,因为 date 存储在 varchar 列中,格式为 dd/mm/yyyy。

SELECT * 
FROM   tablname 
WHERE  date BETWEEN '10/11/2011' AND '10/15/2011'

如果我的日期以 dd/mm/yyy 格式存储,如何找到两个日期之间的值?

请问有谁能帮帮我吗?

提前致谢

【问题讨论】:

  • 列类型是varchar还是DATE?
  • 最好使用时间戳time() 减去两者并转换为人类可读的日期/时间。

标签: php mysql sql date


【解决方案1】:

如果您确实必须将数据保存为 varchar,那么您不必先将其拉入 PHP。您可以为此使用 MySQL 的日期时间函数

http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_str-to-date

SELECT STR_TO_DATE(YourDateColumn,'%d/%m/%Y') AS RealDateColumn 
FROM YourTable

或许

SELECT *
FROM YourTable
WHERE STR_TO_DATE(YourDateColumn,'%d/%m/%Y')  < '2011-01-01'

【讨论】:

  • +1 不知道那个功能。每天学习新东西!
  • 不要忘记“接受”您认为真正回答了您的问题的任何答案。
【解决方案2】:

如果您将日期存储在 VARCHAR 中,而不是 MySQL 的 DATE 列类型之一,那么您需要使用 MySQL 的 STR_TO_DATE 函数(请参阅 Cylindric 的答案)。

当然,最好将列类型更改为DATE or DATETIME 类型。为此,您最好使用新类型创建一个新列,将现有列中的数据从字符串转换为日期,删除现有列并将新列重命名为旧列的名称。

【讨论】:

  • 您不必全部在 PHP 中完成。只需在 MySQL 中转换为 DATETIME。您的建议需要在每次请求时将所有数据发送到页面。
  • @JNK 不了解 STR_TO_DATE 函数,对 Cylindric 的回答表示赞同。但第二部分仍然存在。 OP 应该将列类型转换为 MySQL 的原生 DATETIME 类型之一。
  • @liquorvicar 我同意使用适当的数据类型,但我担心您会认为将所有数据传递到应用层进行转换是个好主意。
  • @JNK 我认为这不是一个好主意。我只是没有意识到你可以在 MySQL 中做到这一点。我已经习惯于使用原生的 DATETIME 类型,我从来没有真正想过日期的字符串操作是可能的(但仍然不是一个好主意!)
【解决方案3】:

将日期存储为 varchar 存在许多问题,包括:占用更多空间、您可以输入非日期值以及字符串无法正确比较。

所以,简短的回答是:不要将日期存储为字符串!

稍长一点的答案是将 varchar 转换为 DATE 类型,然后进行比较。由于转换并不是世界上最有效的事情,因此只需执行一次并存储它。要么只添加一个新列并转换原始日期值(这是我要做的),要么选择一种修改表格的方法来更改当前日期列的类型(这可能更“正确”方法,但它需要更多的工作,并且取决于您当前使用数据的方式,可能会破坏事情)。

【讨论】:

    【解决方案4】:

    正如前面的答案所表明的,最好将日期存储为日期类型。在某些用例中,将日期存储为字符串可能是有意义的。在这种情况下,您应该将日期存储为 YYYYMMDD,这反过来又允许在排序之间按预期工作。

    话虽如此,您可以使用 substring/concat 函数来实现您的目标。比如:

    SELECT * FROM tablname WHERE
    CONCAT(substring(`date`,7,4),substring(`date`,1,2),substring(`date`,3,2)) 
    BETWEEN
    CONCAT(substring('10/11/2011',7,4),substring('10/11/2011',1,2),substring('10/11/2011',3,2)) AND
    CONCAT(substring('10/11/2011',7,4),substring('10/11/2011',1,2),substring('10/11/2011',3,2));
    

    我相信不推荐这种方法的原因很明显。

    【讨论】:

    • 感谢您的回复,但很抱歉,此查询无效。您能否根据我的要求向我发送确切的查询?或为此目的的任何简单查询?
    • 我在日期周围添加了一些反引号,因为它是一个保留字。但是你真的需要花点时间去学习更多关于 sql 的知识。
    猜你喜欢
    • 2017-07-20
    • 2012-03-05
    • 2016-01-02
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多