是否指定按顺序执行INSERT IGNORE ... SELECT?

时间:2020-10-26 15:15:11

标签: sql duplicates mariadb sql-order-by sql-insert

MariaDB INSERT IGNORE... SELECT语法在https://mariadb.com/kb/en/insert/处定义。

我还基于这样一种假设,在这种情况下,每个INSERT都将按照SELECT子句结果集的顺序执行。

测试用例:

DROP TEMPORARY TABLE IF EXISTS index_and_color;
CREATE TEMPORARY TABLE index_and_color (`index` INT PRIMARY KEY, color TEXT);
INSERT IGNORE INTO index_and_color SELECT 5, "Red" UNION ALL SELECT 5, "Blue";
SELECT * FROM index_and_color;

直觉上,我看到SELECT子句结果集中的“第一”行有(5, "Red"),然后忽略了“第二”行,其中包含与“ Blue”相同的键。

从我看来,这是未定义的行为,因为另一台实现相同文档的服务器可以按不同顺序处理行。

我在这里的使用确实依赖未定义的行为吗?

2 个答案:

答案 0 :(得分:1)

什么是“未定义行为”是UNION ALL查询返回的行的顺序。如果需要稳定的结果,请使用ORDER BY子句:

INSERT IGNORE INTO index_and_color (`index`, color)
SELECT 5 `index`, 'Red' color UNION ALL SELECT 5, 'Blue' ORDER BY color;

答案 1 :(得分:0)

SQL语句SELECT * FROM index_and_color应该完全满足您的要求:给定表中的所有数据行。

如果您希望结果集将按特定顺序交付,则需要添加一个ORDER BY子句,否则它可能按索引排序,或者基于优化器期望生成数据的算法最快的。

例如::

CREATE TABLE t1 (a int, b int, index(a));
INSERT INTO t1 VALUES (2,1),(1,2);

/* Here we get the order from last insert statement */
SELECT a,b FROM t1;
MariaDB [test]> select a,b from t1;
+------+------+
| a    | b    |
+------+------+
|    2 |    1 |
|    1 |    2 |
+------+------+

/* Here we get the another order since the optimizer will deliver results from index */
SELECT a FROM t1;
+------+
| a    |
+------+
|    1 |
|    2 |
+------+