将SQL查询包装到外部Select会导致Order By reshuffle

时间:2013-09-18 22:41:21

标签: sql oracle sql-server-2008 tsql

我有一个构建查询的引擎。所以这不是静态的,这就是为什么我必须走这条路(下图)。此外,它适用于SQL和Oracle(Oracle添加了不同的包装器,RowNum等...)。我没有简单的方法来测试Oracle,但下面是SQL Server问题,逐步逻辑

让我们进行简单的查询

Select field1 as f1, myDate dateFld From table1 t1 Where t1.field2 = 1

我可能会或可能不会,union输出另一个表

Select field1, myDate dateFld as f1 From table1 t1 Where t1.field2 = 1
Union
Select field2, myDate dateFld as f1 From table2 t2 Where t2.field2 = 2

我只需要从此联盟中获取 N 记录

Select Top(N) * 
From
   ( 
    Select field1 as f1, myDate dateFld From table1 t1 Where t1.field2 = 1
    Union
    Select field2 as f1, myDate dateFld From table2 t2 Where t2.field2 = 2
   ) Union_Tbl_Alias
Order By dateFld Desc, f1 

请记住这个“按顺序排列”

我也有选择子查询(我只能在Select中使用它们),我转移到另一个Select包装器

Select 
    f1, 
    myDate,
    (Select field99 From table99 t99 Where t99.f1 = Outer_Tbl_Alias.f1) as f3
From
    (
        Select Top(N) * 
        From
           ( 
            Select field1 as f1, myDate dateFld From table1 t1 Where t1.field2 = 1
            Union
            Select field2 as f1, myDate dateFld From table2 t2 Where t2.field2 = 2
           )
        Order By dateFld Desc, f1
    ) Outer_Tbl_Alias

所以问题是最外面的选择重新洗牌记录了一下。他们不再对dateFld Desc进行排序。 我不想推测,我认为这只是SQL Server问题,但我也会在oracle中测试它。将“Order By”移动到最外层语句会为SQL Server修复它。

但我想知道:

1 - 为什么会发生?

2 - 是否有提示告诉SQL服务器 - 保持内部选择的顺序?

1 个答案:

答案 0 :(得分:3)

这种行为似乎有意义。您的外部查询不包含ORDER BY子句,因此结果的顺序是任意的。行可能已在子查询中排序的事实不受控制(尽管它无疑最终会影响结果的顺序)。由于您以编程方式构建查询,因此添加所需的任何ORDER BY子句比尝试解决该问题更有意义(并且我不知道解决该问题的方法是什么保证每次都工作。)

当您针对Oracle数据库运行并针对带有TOP谓词的几个嵌套查询切换rownum时,您将遇到完全相同的问题。保证结果顺序的唯一方法是添加ORDER BY子句。因为无论您使用的数据库是什么都是必要的,所以通过向外部查询添加额外的ORDER BY而不是使用不同的特定于数据库的解决方法来正确地执行此操作更为有意义。