【问题标题】:SQL query for MYSQL for BETWEEN dates is not inclusive of the specified range?MYSQL 的 BETWEEN 日期的 SQL 查询不包括指定范围?
【发布时间】:2018-10-30 07:41:27
【问题描述】:

我正在尝试为 MYSQL 创建一个 SQL 语句来检索日期范围之间的记录。我希望返回包含指定范围的两个日期的记录。目前这还没有发生。请问有人可以建议吗?

我的 SQL-PHP:

 $fromDate = '21-SEP-2018';
 $toDate = '29-SEP-2018';

 $sql = "SELECT * FROM myTable WHERE zapDocUserId='$USER_ID' AND dateUpload BETWEEN \"$fromDate\" AND \"$toDate\" ORDER BY dateUpload DESC";
 $result = $mysqli -> query($sql);

我返回的记录不包括日期为 21-SEP-2018 和 29-SEP-2018 的记录。我希望它被包括在内。

【问题讨论】:

  • '21-SEP-2018' 不是 MySQL 日期格式。 dateUpload 列的数据类型是什么?我怀疑是字符串类型的。

标签: php mysql sql


【解决方案1】:

不要使用between 作为日期。问题在于时间部分。 Aaron Bertrand 有一个很好的博客 (What do BETWEEN and the devil have in common?)。虽然面向 SQL Server,但它适用于任何数据库。

你似乎想要:

SELECT *
FROM myTable
WHERE zapDocUserId = '$USER_ID' AND
     dateUpload >= '$fromDate' AND 
      dateUpload < '$toDate' + interval 1 day
ORDER BY dateUpload DESC;

当然,这并不能修复您的日期格式。那是另一回事。但是,您不应该仅仅修复日期格式。您应该学习如何将参数传递到查询中,以便查询从正确的类型开始。使用占位符,查询看起来更像:

SELECT *
FROM myTable
WHERE zapDocUserId = ? AND
     dateUpload >= ? AND 
      dateUpload < ? + interval 1 day
ORDER BY dateUpload DESC;

【讨论】:

  • 非常好的答案,非常感谢,即使是在 2021 年!
【解决方案2】:

您的日期文字在 MySQL(或许多其他风格的 SQL)中无效。如果您使用有效的格式,则查询应该可以工作。此外,您真的应该在 PHP 代码中使用准备好的语句。考虑到这两个因素,以下应该有效:

$fromDate = '2018-09-21';
$toDate = '2018-09-29';
$sql = "SELECT * FROM myTable WHERE zapDocUserId = ? AND dateUpload BETWEEN ? AND ? ";
$sql .= "ORDER BY dateUpload DESC";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('iss', $USER_ID, $fromDate, $toDate);
$stmt->execute();

这假定您的 dateUpload 列是正确的日期类型列。如果dateUpload 实际上是文本,并且您将日期存储为例如21-SEP-2018,那么您还必须调用 STR_TO_DATE 来转换表格中的日期:

$sql = "SELECT * FROM myTable WHERE zapDocUserId = ? AND ";
$sql .= "STR_TO_DATE(dateUpload, '%d-%b-%Y') BETWEEN ? AND ? ";
$sql .= "ORDER BY dateUpload DESC";

See here 阅读有关 MySQL 日期和时间文字规则的更多信息。

【讨论】:

  • RDB 不支持这些日期吗?
  • @jarlh 你是在逗我还是这是一个实际的问题?
  • SQL 世界中存在这些日期只是客套话。
  • @jarlh Tim 的观点是,只要涉及 MySQL,您放在 VARCHAR 列中的任何内容都只是文本。您可以编写代码来解析此类文本并将其转换为其他类型(整数、小数、日期......),只要文本是可解析的,但一般而言,它是需要明确完成的手动工作。
  • @ÁlvaroGonzález,完全同意。
【解决方案3】:

解决问题的一个非常简单的方法是使用CAST(&lt;field&gt; AS DATE) 子句。这将从查询中删除计时组件:

$fromDate = '2018-09-21';
$toDate = '2018-09-29';
$sql = "SELECT * FROM myTable WHERE zapDocUserId = ? AND CAST(dateUpload AS DATE) BETWEEN ? AND ? ";
$sql .= "ORDER BY dateUpload DESC";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('iss', $USER_ID, $fromDate, $toDate);
$stmt->execute();

在此示例中,CAST(dateUpload AS DATE) — 从比较中删除时间组件并仅使用日期的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多