mysql 使用 BETWEEN 或 >= & <= 时查询 returns 超出 WHERE 范围的值
mysql query returns values outside of WHERE range when using BETWEEN or >= & <=
我很难过。我在 MySQL 数据库中有一个日期字段,我从 csv 文件中填充了该字段。日期字段采用 mdy 格式,因此它可以有前导零(我认为这是问题所在)。因此,2015 年 8 月 9 日在 CSV 文件中为 080915,但在数据库中为 80915。此字段为 INT(6)
所以我有一个问题:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt = 080915;
这非常有效。
我的数据库不包含 010115 之前的任何数据。
所以如果我使用:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt = 080914;
我没有得到任何结果,这是正确的。
但是,如果我使用:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt <= 080914;
我得到了从 010115 到 080915 的所有数据..
如果我使用这样的范围:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080915 AND invdt <= 083115;
我得到了那个范围内的正确数据,但是如果我使用:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080914 AND invdt <= 083114;
我得到了所有相同的数据,就好像日期范围是 2015 年一样,即使日期是 2014 年。它应该 return 什么都没有,因为该数据不存在。
所以我尝试将字段更改为 VARCHAR 而不是 INT,认为前导零将其丢弃。
我从 CSV 文件加载数据并查看它,它现在显示条目为 080915(具有前导零)。
我不确定 varchar 是否可以在大于和小于容量的情况下工作,但它似乎工作正常,只要数据存在。如果不是,它仍然是 returns 值,就像字段是 INT 值时一样。
如果我使用 WHERE invdt = 080915,我会得到我应该得到的结果,如果我使用 WHERE invdt = 080914,我不会得到任何结果(我应该得到)。我可以用引号也可以不用引号,但我仍然能得到正确的结果。一旦我尝试使用 BETWEEN 或 <= 和 >= 或它们的任意组合,如果数据库中不存在日期,我就会得到我指定的日期范围之外的数据。
所以这个查询:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080915 AND invdt <= 083115;
returns 与以下数据完全相同:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080914 AND invdt <= 083114;
???
无论字段是 INT 还是 VARCHAR,080914 都与 080915 相同。
我在这里错过了什么?
您不是在比较日期,而是在比较 int(6)。
如果您要比较存储在整数中的日期,那么将它们存储为最重要的数字优先作为 yymmdd 会更有意义。
083115和080314只相差1,也就是一年。
如果您将其视为它们如何从最小到最大排序以及它们代表什么,我认为这是有道理的。
您使用的日期格式似乎是 MMDDYY
。正如您所说,这些是代表日期的整数。
但是,它们不能很好地表示日期。为什么?毫无疑问,2015 年 8 月 16 日是在 2014 年 8 月 17 日之后。但是整数 081615 比 081714 小。所以你的日期范围比较都搞砸了。
如果您可以将 table 中的 invdt
列更改为 DATE
数据类型,您应该这样做。在 table、
中创建一个名为 invdt 的新列
ALTER TABLE invoices ADD COLUMN invdate DATE
然后发布此更新。它使用 STR_TO_DATE()
to format your date information correctly.
UPDATE invoices SET invdate = STR_TO_DATE(invdt, '%m%d%y')
然后您可以发出 SELECT 查询,例如
SELECT SUM(amt) as sum_amt
FROM invoices
WHERE invdate >= '2015-08-31'
AND invdate <= '2015-09-08'
您甚至可以进行很酷的日期运算。例如,这会生成最近两周的每日发票摘要。
SELECT SUM(amt) as sum_amt,
invdate
FROM invoices
WHERE invdate >= CURDATE() - INTERVAL 14 DAY
AND invdate < CURDATE()
GROUP BY invdate
如果你不能改变你的table,那么你需要像这样使用STR_TO_DATE()
。
SELECT SUM(amt) as sum_amt
FROM invoices
WHERE STR_TO_DATE(invdt,'%m%d%y') >= '2015-08-31'
AND STR_TO_DATE(invdt,'%m%d%y') <= '2015-09-08'
我很难过。我在 MySQL 数据库中有一个日期字段,我从 csv 文件中填充了该字段。日期字段采用 mdy 格式,因此它可以有前导零(我认为这是问题所在)。因此,2015 年 8 月 9 日在 CSV 文件中为 080915,但在数据库中为 80915。此字段为 INT(6)
所以我有一个问题:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt = 080915;
这非常有效。 我的数据库不包含 010115 之前的任何数据。 所以如果我使用:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt = 080914;
我没有得到任何结果,这是正确的。 但是,如果我使用:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt <= 080914;
我得到了从 010115 到 080915 的所有数据.. 如果我使用这样的范围:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080915 AND invdt <= 083115;
我得到了那个范围内的正确数据,但是如果我使用:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080914 AND invdt <= 083114;
我得到了所有相同的数据,就好像日期范围是 2015 年一样,即使日期是 2014 年。它应该 return 什么都没有,因为该数据不存在。
所以我尝试将字段更改为 VARCHAR 而不是 INT,认为前导零将其丢弃。 我从 CSV 文件加载数据并查看它,它现在显示条目为 080915(具有前导零)。 我不确定 varchar 是否可以在大于和小于容量的情况下工作,但它似乎工作正常,只要数据存在。如果不是,它仍然是 returns 值,就像字段是 INT 值时一样。
如果我使用 WHERE invdt = 080915,我会得到我应该得到的结果,如果我使用 WHERE invdt = 080914,我不会得到任何结果(我应该得到)。我可以用引号也可以不用引号,但我仍然能得到正确的结果。一旦我尝试使用 BETWEEN 或 <= 和 >= 或它们的任意组合,如果数据库中不存在日期,我就会得到我指定的日期范围之外的数据。 所以这个查询:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080915 AND invdt <= 083115;
returns 与以下数据完全相同:
SELECT sum(amt) as sum_amt FROM invoices WHERE invdt >= 080914 AND invdt <= 083114;
???
无论字段是 INT 还是 VARCHAR,080914 都与 080915 相同。
我在这里错过了什么?
您不是在比较日期,而是在比较 int(6)。 如果您要比较存储在整数中的日期,那么将它们存储为最重要的数字优先作为 yymmdd 会更有意义。 083115和080314只相差1,也就是一年。 如果您将其视为它们如何从最小到最大排序以及它们代表什么,我认为这是有道理的。
您使用的日期格式似乎是 MMDDYY
。正如您所说,这些是代表日期的整数。
但是,它们不能很好地表示日期。为什么?毫无疑问,2015 年 8 月 16 日是在 2014 年 8 月 17 日之后。但是整数 081615 比 081714 小。所以你的日期范围比较都搞砸了。
如果您可以将 table 中的 invdt
列更改为 DATE
数据类型,您应该这样做。在 table、
ALTER TABLE invoices ADD COLUMN invdate DATE
然后发布此更新。它使用 STR_TO_DATE()
to format your date information correctly.
UPDATE invoices SET invdate = STR_TO_DATE(invdt, '%m%d%y')
然后您可以发出 SELECT 查询,例如
SELECT SUM(amt) as sum_amt
FROM invoices
WHERE invdate >= '2015-08-31'
AND invdate <= '2015-09-08'
您甚至可以进行很酷的日期运算。例如,这会生成最近两周的每日发票摘要。
SELECT SUM(amt) as sum_amt,
invdate
FROM invoices
WHERE invdate >= CURDATE() - INTERVAL 14 DAY
AND invdate < CURDATE()
GROUP BY invdate
如果你不能改变你的table,那么你需要像这样使用STR_TO_DATE()
。
SELECT SUM(amt) as sum_amt
FROM invoices
WHERE STR_TO_DATE(invdt,'%m%d%y') >= '2015-08-31'
AND STR_TO_DATE(invdt,'%m%d%y') <= '2015-09-08'