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'