为什么这个简单的SQL语句不起作用?

时间:2009-12-24 21:49:38

标签: sql mysql database datetime timestamp

dateposted是MySQL TIMESTAMP列:

 SELECT * 
   FROM posts 
  WHERE dateposted > NOW() - 604800

... 应该,如果我没弄错的话,返回上周dateposted所在的行。但它只返回不到一天大的帖子。我的印象是TIMESTAMP用了几秒钟?

IE:7 * 3600 * 24 = 604800

5 个答案:

答案 0 :(得分:13)

使用:

WHERE dateposted BETWEEN DATE_ADD(NOW(), INTERVAL -7 DAY) AND NOW()

答案 1 :(得分:4)

这是因为now()从时间戳隐式转换为数字,而mysql转换规则会创建一个数字,如YYYYMMDDHHMMSS.uuuuuu

来自mysql docs:

mysql> SELECT NOW();
        -> '2007-12-15 23:50:26'
mysql> SELECT NOW() + 0;
        -> 20071215235026.000000

答案 2 :(得分:2)

不,您不能隐式使用TIMESTAMPDATETIME和其他与日期相关的数据类型的整数算术。您正在考虑UNIX时间戳格式,这是自1970年1月1日以来的整数秒。

您可以在MySQL中将SQL数据类型转换为UNIX timestamp,然后使用算术:

SELECT * FROM posts WHERE UNIX_TIMESTAMP(dateposted)+604800 > NOW()+0;

注意:向NOW()添加零会使其返回数值而不是字符串值。


更新:好的,我对上述查询完全错了。将NOW()转换为数字输出不会生成可与UNIX时间戳进行比较的数字。它产生一个数字,但数字不计算秒数或其他任何数字。数字只是YYYYMMDDHHMMSS串在一起。

示例:

CREATE TABLE foo (
  id SERIAL PRIMARY KEY,
  dateposted TIMESTAMP
);

INSERT INTO foo (dateposted) VALUES ('2009-12-4'), ('2009-12-11'), ('2009-12-18');

SELECT * FROM foo;

+----+---------------------+
| id | dateposted          |
+----+---------------------+
|  1 | 2009-12-04 00:00:00 |
|  2 | 2009-12-11 00:00:00 |
|  3 | 2009-12-18 00:00:00 |
+----+---------------------+

SELECT *, UNIX_TIMESTAMP(dateposted) AS ut, NOW()-604800 AS wk FROM foo

+----+---------------------+------------+-----------------------+
| id | dateposted          | ut         | wk                    |
+----+---------------------+------------+-----------------------+
|  1 | 2009-12-04 00:00:00 | 1259913600 | 20091223539359.000000 |
|  2 | 2009-12-11 00:00:00 | 1260518400 | 20091223539359.000000 |
|  3 | 2009-12-18 00:00:00 | 1261123200 | 20091223539359.000000 |
+----+---------------------+------------+-----------------------+

很明显,数值不具有可比性。但是,UNIX_TIMSTAMP()也可以转换该格式的数值,因为它可以转换时间戳的字符串表示形式:

SELECT *, UNIX_TIMESTAMP(dateposted) AS ut, UNIX_TIMESTAMP(NOW())-604800 AS wk FROM foo

+----+---------------------+------------+------------+
| id | dateposted          | ut         | wk         |
+----+---------------------+------------+------------+
|  1 | 2009-12-04 00:00:00 | 1259913600 | 1261089774 |
|  2 | 2009-12-11 00:00:00 | 1260518400 | 1261089774 |
|  3 | 2009-12-18 00:00:00 | 1261123200 | 1261089774 |
+----+---------------------+------------+------------+

现在可以使用比较它们的表达式运行查询:

SELECT * FROM foo WHERE UNIX_TIMESTAMP(dateposted) > UNIX_TIMESTAMP(NOW())-604800

+----+---------------------+
| id | dateposted          |
+----+---------------------+
|  3 | 2009-12-18 00:00:00 |
+----+---------------------+

但@OMGPonies给出的答案仍然更好,因为我的查询中的这个表达式可能无法使用索引。我只是提供这个作为TIMESTAMPNOW()功能如何工作的解释。

答案 3 :(得分:2)

也许在内心。这样做的方法是日期数学函数。所以它会是:

SELECT * FROM posts WHERE dateposted > DATE_ADD(NOW(), INTERVAL -7 DAY)

我认为有一个DATE_SUB,我只是习惯在任何地方使用ADD。

答案 4 :(得分:1)

尝试此查询:

SELECT * FROM posts WHERE DATE_SUB(CURDATE(),INTERVAL 7 DAY) < dateposted;

我假设您正在使用mySQL。