繁体   English   中英

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

[英]Why won't this simple SQL statement work?

dateposted是MySQL TIMESTAMP列:

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

...... 应该 ,如果我没有记错的话,回行,其中dateposted是在上周。 但它只返回不到一天大的帖子。 我觉得TIMESTAMP用了几秒钟?

IE:7 * 3600 * 24 = 604800

采用:

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

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

来自mysql文档:

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

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

您可以将SQL数据类型转换为MySQL中的UNIX时间戳 ,然后使用算术:

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()功能如何工作的解释。

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

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

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

试试这个查询:

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

我假设您正在使用mySQL。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM