我有一个以奇怪方式工作的 mysql 查询。我发布了输入数据已更改的 2 个查询,输出列在每个查询下。
查询 1(要注意的区域 BETWEEN '13/05/11' AND '30/05/11'
):
SELECT COUNT(pos_transaction_id) AS total, DATE_FORMAT(pt.timestamp,'%d-%m-%Y %H:%i:%S') AS Date, SUM(amount) AS amount FROM pos_transactions pt WHERE DATE_FORMAT(pt.timestamp,'%e/%m/%y') BETWEEN '13/05/11' AND '30/05/11' GROUP BY WEEK(pt.timestamp) ORDER BY pt.timestamp
输出:
查询 2(要注意的区域 BETWEEN '3/05/11' AND '30/05/11'
):
SELECT COUNT(pos_transaction_id) AS total, DATE_FORMAT(pt.timestamp,'%d-%m-%Y %H:%i:%S') AS Date, SUM(amount) AS amount FROM pos_transactions pt WHERE DATE_FORMAT(pt.timestamp,'%e/%m/%y') BETWEEN '3/05/11' AND '30/05/11' GROUP BY WEEK(pt.timestamp) ORDER BY pt.timestamp
输出:
现在,当第二个查询中的范围增加时,为什么我只得到一条记录?甚至在第一个查询中,我也得到了超出范围的记录。有什么问题吗??
编辑
更改后的查询看起来像这样,但仍然没有执行我希望它执行的操作。
SELECT COUNT(pos_transaction_id) AS total, DATE_FORMAT(pt.timestamp,'%d-%m-%Y %H:%i:%S') AS Date, SUM(amount) AS amount FROM pos_transactions pt WHERE DATE_FORMAT(pt.timestamp,'%e/%m/%y') BETWEEN STR_TO_DATE('01/05/11','%e/%m/%y') AND STR_TO_DATE('30/05/11','%e/%m/%y') GROUP BY WEEK(pt.timestamp) ORDER BY pt.timestamp
输出是:
最佳答案
我认为您正在看到两种不良做法交集的结果。
首先,date_format() 函数返回一个字符串。您的 WHERE 子句进行字符串比较。在 PostgreSQL 中
select '26/04/2011' between '13/05/11' AND '30/05/11';
--
T
那是因为字符串“26”在字符串“13”和“30”之间。但是,如果您将它们写为日期,PostgreSQL 会正确地告诉您“2011-04-26”(遵循我服务器上的日期样式设置)不在该范围内。
其次,我猜测出现奇怪的超出范围的值是因为您在聚合中使用了不确定的表达式。表达式 WEEK(pt.timestamp)
没有出现在 SELECT 列表中。我认为如果您尝试这样做,市场上的所有其他 SQL 引擎都会抛出错误。由于它不在 SELECT 列表中,MySQL 将从该聚合范围返回一个明显随机的值。
要避免此类错误,请不要对日期或时间戳范围进行字符串比较,也不要使用不确定的聚合表达式。
发布 DDL 和最少的 SQL INSERT 语句来重现问题可以帮助人们帮助您。
关于mysql - 请解释以下查询的工作原理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6167738/