2016-09-26 46 views
0

我们有多个MSSQL服务器具有相同的数据库副本,下面的查询返回所有服务器的有效顺序(除了一个),我仔细检查了表的设计和所有外观除了几台服务器之外,其他部分都缺少索引。由学说一个MS SQL服务器为查询返回错误订单

WITH dctrn_cte AS (
    SELECT TOP 10 a0_.Priority 
    FROM PROJECTS a0_ 
    WHERE a0_.ProjectID = 1234 
    AND (a0_.Check1 > 0 
      OR 
      a0_.Check2 > 0) 
    AND a0_.Active = 1 
    ORDER BY a0_.Priority DESC) 
    SELECT * 
    FROM (
     SELECT *, ROW_NUMBER() 
     OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte 
    ) AS doctrine_tbl 
    WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum ASC 

产生

查询中的每个查询的是,特定的服务器上执行时,它给出了一个随机的顺序 - 它完全忽略了ORDER BY部分。

+0

哪个'order by'?三者中唯一有意义的是第一个选择10行。正如行编号中使用的那样,因此在最后的顺序中使用的是完全不确定的,并且不保证任何东西。 –

+0

你为什么使用'SELECT 0'?你认为会发生什么? –

回答

5

您的查询最后有一个ORDER BY子句:doctrine_rownum。这是一个未定值列的别名:

ROW_NUMBER() 
    OVER (ORDER BY (SELECT 0)) AS doctrine_rownum 

因此,任何结果顺序都是正确的顺序。所有的服务器都会返回正确的结果。 Select isn't broken

PS。您在CTE内部还有一个ORDER BY,这与最终订单无关,因为它不会对最终结果或doctrine_rownum值施加任何顺序。

该查询由教义

产生的查询由教义产生错误,无论这个学说是。

+1

CTE中的“Order by”确定CTE选择了哪10行,因此它与最终结果并不完全无关。虽然这与结果的顺序无关。 –

+0

@TabAlleman是真的。我的措辞很差。 –

+0

感谢Remus&Tab - 发布的查询是一个非常简化的版本 - 我们使用[doctrine](http://www.doctrine-project.org/)构建动态查询,而CTE部分由它提供。我将调查使用的捆绑包,看看我能否改进它。 –

-2

添加OPTION (MAXDOP 1)修复了该服务器上的订单。

+2

“修复”和改变内容之间有区别,以便您使用的不可靠机制受到影响,并随后趋向于匹配您想要的内容。解决这个问题将理解为什么它现在不是确定性的,并且改变你的数据库代码以确定它。 – btberry

+0

你是对的 - 我们正在寻找一种快速的方法来临时“修复”问题而不中断/延迟部署,特别是排序是一项高优先级要求。谢谢。 –

相关问题