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

时间:2018-03-02 23:52:31

标签: mysql sql sql-order-by

我正在测试我的应用程序(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天的调查,眼泪,甚至糟糕的数据库梦想,到了晚上,事实证明这个bug在查询中有时会返回不同的结果。它是这样的

+-----+--------------+-----------+------+--------+
| 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";

此查询有时会返回1然后返回2,其他时间则返回2然后返回1.

我通过添加额外级别来排序ID

来修复查询
$query = "SELECT * FROM table ORDER BY date, direction, col3, ID";

但是我不明白为什么MySQL的行为会这样?换句话说,对于所有按行列相同的行,MySQL会遵循哪些规则?以及为什么会改变?

1 个答案:

答案 0 :(得分:1)

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

这实际上很明显。 SQL表表示无序集。除非列指定了排序,否则没有排序。

所以,通过将id作为最终关键字,你做了正确的事情。这样可以确保订单定义明确,因为没有重复的密钥。