当使用BETWEEN或> =& amp;时,mysql查询返回WHERE范围之外的值< =

时间:2015-08-20 19:34:07

标签: mysql where

我很难过。我在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年。由于数据不存在,它应该只返回任何内容。

所以我尝试将字段更改为VARCHAR而不是INT,认为前导零将其丢弃。 我从CSV文件中加载了数据并查看了它,现在显示该条目的080915(具有前导零)。 我不确定varchar是否可以在大于和小于容量的情况下工作,但只要数据存在,它似乎工作正常。如果没有,它仍然返回值,就像字段是INT值时一样。

如果我使用WHERE invdt = 080915我得到了一个结果,如果我使用WHERE invdt = 080914我得不到结果(我应该)。我可以使用和不使用引号来执行此操作,但仍然可以获得正确的结果。一旦我尝试使用BETWEEN或&lt; =和&gt; =或其任意组合,我就会在我指定的日期范围之外获取数据,如果数据库中不存在日期。 所以这个查询:

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;

???

无论字段是INT还是VARCHAR,它的行为都与080914相同。
我在这里缺少什么?

2 个答案:

答案 0 :(得分:0)

您没有比较您正在比较int(6)的日期。 如果你要比较存储在整数中的日期,那么将它们作为yymmdd存储为最重要的数字会更有意义。 083115和080314之间的区别仅为1,即一年。 如果你把它看作是从最小到最大的排序以及它们所代表的东西,我认为它会有意义。

答案 1 :(得分:0)

看起来您使用的日期格式为MMDDYY。如你所说,这些是表示日期的整数。

但是,它们代表的日期很差。为什么?毫无疑问,2015年8月16日是在2014年8月17日之后。但整数081615 小于而不是081714.所以你的日期范围比较都被搞砸了。

如果您可以将表中的invdt列更改为DATE数据类型,则应该这样做。在表中创建一个名为invdt的新列

ALTER TABLE invoices ADD COLUMN invdate DATE

然后发出此更新。它使用STR_TO_DATE()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

如果无法更改您的表格,那么您需要使用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'