带有 order 子句的相同查询,相同的数据集,但结果不同

same query with order clause, same dataset, but different result

我正在通过编写一个测试器来测试我的应用程序(一个 ERP 系统),该测试器将执行类似这样的 30 个步骤的固定场景

//pseudo code(PHP)
public function runScenario1Test(){
    V2_1Tester::resetDatabase();
    V2_1Tester::insert60Companies();
    V2_1Tester::insert2000Items();
    V2_1Tester::insert100Purchases();
    V2_1Tester::insert100Sales();

    //do some other stuff

    V2_1Tester:checkResults();
}

虽然每次我运行测试相同的代码,相同的数据,所有输入都是相同的,但有时我得到的结果不同!!!

我的脑袋快要爆炸了,经过 4 天的调查、流泪,甚至整晚都做了糟糕的数据库梦,结果发现错误出在有时 returns 不同结果的查询中。是这样的

+-----+--------------+-----------+------+--------+
| ID  |     date     | direction | col3 |  col4  |
+-----+--------------+-----------+------+--------+
|  1  |  2018-03-03  |     in    |   6  | 100.50 |
|  2  |  2018-03-03  |     in    |   6  | 350.75 |
+-----+--------------+-----------+------+--------+
-- more ~ 3000 rows

$query = "SELECT * FROM table ORDER BY date, direction, col3";

此查询有时 returns 1 然后 2,有时 2 然后 1。

我通过添加额外的排序级别来修复查询 ID

$query = "SELECT * FROM table ORDER BY date, direction, col3, ID";

但我不明白为什么 MySQL 会这样?换句话说 MySQL 对相同的行将遵循什么规则所有排序列?为什么会发生变化?

在SQL中,order by不稳定。这意味着当键相同时,排序可以是任意顺序。

这其实是显而易见的。 SQL 个表代表 无序 个集合。除非列指定排序,否则没有排序。

所以,您将 id 作为最后的密钥是正确的。这可确保顺序为 well-defined,因为没有重复键。