php - 'get ID of the last updated row in MySQL' 这个技巧是如何工作的?

标签 php mysql

我试图选择我的表的最后更新的行 ID,然后我发现这个问题 How to get ID of the last updated row in MySQL? .

SET @uids := null;
UPDATE footable
   SET foo = 'bar'
 WHERE fooid > 5
   AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;

该解决方案有效,但我不明白为什么我必须将 @uids 设置为 null 而不是空字符串。为什么即使附加了限制子句,该语句也仅选择受影响的行而不是匹配的行。这是 MySQL 定义的行为吗?我应该查阅 MySQL 手册的哪一页?

mysql> select * from transaction_test;
+----+--------+------------+
| id | value1 | value2     |
+----+--------+------------+
|  1 |      1 | 1460600984 |
|  2 |      2 | 1460598960 |
+----+--------+------------+
2 rows in set (0.00 sec)

mysql>  set @ids=null;update  transaction_test set value2=unix_timestamp(now()) where 1=1 and  ( SELECT @ids:=concat_ws(',',@ids,value1)  ) limit 1;select @ids;
Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

+------+
| @ids |
+------+
| 1    |
+------+
1 row in set (0.00 sec)

mysql>  set @ids='';update  transaction_test set value2=unix_timestamp(now()) where 1=1 and  ( SELECT @ids:=concat_ws(',',@ids,value1)  ) limit 1;select @ids;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

+------+
| @ids |
+------+
| ,1,2 |
+------+
1 row in set (0.00 sec)

最佳答案

如果将 @uids 初始化为空字符串,则 CONCAT_WS(',', fooid, @uids) 将生成 fooid, 在进行第一次连接时,而不只是 fooid ,因为它将使用逗号将 fooid'' 连接起来。但是,当 CONCAT_WS() 的任何参数为 NULL 时,它会被完全忽略,并且在它和相邻元素之间不会放置逗号。

它仅选择受影响的行,因为 AND 执行短路。这意味着参数是从左到右计算的,如果第一个参数为 FALSE,则根本不会计算第二个参数。因此,当 fooid > 5TRUE 时,它仅执行 @uids := ... 赋值。

如果您有 LIMIT 子句,则行为取决于您排序所依据的列是否已建立索引。如果是,它将按顺序扫描索引,然后评估 WHERE 子句,并在达到限制计数时停止,因此只有限制内的行才会包含在 @ 中uids。或者,如果您没有 ORDER BY 子句,它只会扫描表,直到达到限制。

但是,您不能可靠地依赖于此,它取决于查询优化器如何分析查询。

但是如果排序列没有索引,或者查询优化器无法执行上述优化,它可能必须扫描整个表,选择与 WHERE 匹配的所有行子句放入临时表中,然后对其执行排序。在这种情况下,@uids 将包含所有匹配的 ID,而不仅仅是限制内的 ID。您可以使用子查询来解决这个问题。

SET @uids := null;
UPDATE footable AS t1
JOIN (SELECT fooid
      FROM footable
      WHERE fooid > 5
      ORDER BY somecolumn
      LIMIT 10) AS t2
ON t1.fooid = t2.fooid
SET t1.foo = 'bar'
WHERE @uids := CONCAT_WS(',', fooid, @uids);
SELECT @uids;

关于php - 'get ID of the last updated row in MySQL' 这个技巧是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36612702/

相关文章:

php - 使用 PHP 替换以前的图像并向服务器添加新图像

php - Macports 不会安装

javascript - 文件下载命中计数器 PHP、MYSQL

mysql - phpmyadmin登录突然不工作

mysql - 使用 View 从多个表中获取数据

php - ftp_get - 警告 : ftp_get(): Opening BINARY mode data connection

javascript - 返回 false 不会停止表单提交

php - 帮助限制连接的 mysql 数据库查询

mysql - 除以零进行排序过程

php - 忽略 MySQL 查询中的空 "$_POST"值