【问题标题】:SQL Error with Order By in Subquery子查询中的 Order By 的 SQL 错误
【发布时间】:2010-11-02 10:10:05
【问题描述】:

我正在使用 SQL Server 2005。

我的查询是:

SELECT (
  SELECT COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
  GROUP BY refKlinik_id
  ORDER BY refKlinik_id
) as dorduncuay

还有错误:

ORDER BY 子句在视图、内联函数、派生中无效 表、子查询和公用表表达式,除非 TOP 或 FOR 还指定了 XML。

如何在子查询中使用ORDER BY

【问题讨论】:

    标签: sql-server sql-order-by


    【解决方案1】:

    当你有一个 UNION 时,可能需要订购一个子查询:

    您生成所有教师和学生的电话簿。

    SELECT name, phone FROM teachers
    UNION
    SELECT name, phone FROM students
    

    您想先显示所有教师,然后显示所有学生,都按顺序显示。所以你不能应用全局订单。

    一种解决方案是包含一个强制第一次排序的键,然后对名称进行排序:

    SELECT name, phone, 1 AS orderkey FROM teachers
    UNION
    SELECT name, phone, 2 AS orderkey FROM students
    ORDER BY orderkey, name
    

    我认为它比伪造的偏移子查询结果更清楚。

    【讨论】:

      【解决方案2】:

      对于像 OP 显示的简单计数,Order by 并不是严格需要的。如果他们正在使用子查询的结果,则可能是。我正在处理一个类似的问题,并在以下查询中遇到了同样的错误:

      -- 我想要更新日期等于最大更新日期的成本表中的行:

          SELECT * FROM #Costs Cost
          INNER JOIN
          (
              SELECT Entityname, costtype, MAX(updatedtime) MaxUpdatedTime
              FROM #HoldCosts cost
              GROUP BY Entityname, costtype
              ORDER BY Entityname, costtype  -- *** This causes an error***
          ) CostsMax
              ON  Costs.Entityname = CostsMax.entityname
              AND Costs.Costtype = CostsMax.Costtype
              AND Costs.UpdatedTime = CostsMax.MaxUpdatedtime
          ORDER BY Costs.Entityname, Costs.costtype
      

      -- *** 要做到这一点,有几个选项:

      -- 添加一个无关的 TOP 子句,这似乎有点 hack:

          SELECT * FROM #Costs Cost
          INNER JOIN
          (
              SELECT TOP 99.999999 PERCENT Entityname, costtype, MAX(updatedtime) MaxUpdatedTime
              FROM #HoldCosts cost
              GROUP BY Entityname, costtype
              ORDER BY Entityname, costtype  
          ) CostsMax
              ON Costs.Entityname = CostsMax.entityname
              AND Costs.Costtype = CostsMax.Costtype
              AND Costs.UpdatedTime = CostsMax.MaxUpdatedtime
          ORDER BY Costs.Entityname, Costs.costtype
      

      -- **** 创建一个临时表来订购 maxCost

          SELECT Entityname, costtype, MAX(updatedtime) MaxUpdatedTime
          INTO #MaxCost
          FROM #HoldCosts cost
          GROUP BY Entityname, costtype
          ORDER BY Entityname, costtype  
      
          SELECT * FROM #Costs Cost
          INNER JOIN #MaxCost CostsMax
              ON Costs.Entityname = CostsMax.entityname
              AND Costs.Costtype = CostsMax.Costtype
              AND Costs.UpdatedTime = CostsMax.MaxUpdatedtime
          ORDER BY Costs.Entityname, costs.costtype
      

      其他可能的解决方法可能是 CTE 或表变量。但是每种情况都需要您确定最适合您的方法。我倾向于首先查看临时表。对我来说,它是清晰而直接的。 YMMV。

      【讨论】:

        【解决方案3】:

        美好的一天

        对于某些人来说,子查询中的顺序是有问题的。 如果您需要基于某些排序删除某些记录,则必须使用子查询中的 order by。 喜欢

        delete from someTable Where ID in (select top(1) from sometable where condition order by insertionstamp desc)
        

        这样您就可以删除最后一个插入表格的表格。 实际上有三种方法可以执行此删除操作。

        但是,子查询中的order by可以在很多情况下使用。

        对于在子查询中使用order by的删除方法链接如下

        http://web.archive.org/web/20100212155407/http://blogs.msdn.com/sqlcat/archive/2009/05/21/fast-ordered-delete.aspx

        我希望它有所帮助。谢谢大家

        【讨论】:

          【解决方案4】:

          我使用此代码获得第二名的薪水

          我也遇到类似错误

          ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP 或 FOR XML。

          我用来避免错误的 TOP 100

          从 ( select tbl.Coloumn1 ,CONVERT(varchar, ROW_NUMBER() OVER (ORDER BY (SELECT 1))) AS Rowno from ( 从表 1 中选择 前 100 名 * 按 Coloumn1 desc) as tbl) 为 tbl where tbl.Rowno=2

          【讨论】:

            【解决方案5】:

            如果您使用的是 SQL Server 2012 或更高版本,现在很容易解决此问题。添加offset 0 rows

            SELECT (
              SELECT
              COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
              GROUP BY refKlinik_id
              ORDER BY refKlinik_id OFFSET 0 ROWS
            ) as dorduncuay
            

            【讨论】:

            • 在过去 20 分钟内我一直在寻找的所有答案中,这是唯一一个解决了我的问题的答案。
            • 我避免了这个答案,因为它看起来如此多余和毫无意义,肯定会有更好的方法让它发挥作用!......不是。就是这样,这就是你们所有人的答案。多么奇怪的功能。
            • 我在另一个问题here的回答中添加了一个在 SQL Server 的 CTE(临时命名结果集)上使用 ORDER BY 的示例
            • 偏移0行是什么动作?
            【解决方案6】:

            也许这个技巧会对某人有所帮助

            SELECT
                [id],
                [code],
                [created_at]                          
            FROM
                ( SELECT
                    [id],
                    [code],
                    [created_at],
                    (ROW_NUMBER() OVER (
                ORDER BY
                    created_at DESC)) AS Row                                 
                FROM
                    [Code_tbl]                                 
                WHERE
                    [created_at] BETWEEN '2009-11-17 00:00:01' AND '2010-11-17 23:59:59'                                  
                    )  Rows                          
            WHERE
                Row BETWEEN 10 AND    20;
            

            此处按字段 created_at 排序的内部子查询(可以是您表中的任何一个)

            【讨论】:

              【解决方案7】:

              如果构建临时表,请将 ORDER BY 子句从临时表代码块内部移到外部。

              不允许:

              SELECT * FROM (
              SELECT A FROM Y
              ORDER BY Y.A
              ) X;
              

              允许:

              SELECT * FROM (
              SELECT A FROM Y
              ) X
              ORDER BY X.A;
              

              【讨论】:

                【解决方案8】:

                除了 order by 在您的查询中似乎没有意义之外...... 要在子选择中使用 order by,您需要使用 TOP 2147483647。

                SELECT (
                  SELECT TOP 2147483647
                  COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
                  GROUP BY refKlinik_id
                  ORDER BY refKlinik_id
                ) as dorduncuay
                

                我的理解是“TOP 100 PERCENT”不再保证从 SQL 2005 开始的订购:

                在 SQL Server 2005 中,ORDER BY 使用视图定义中的子句 只是为了确定那些是 由 TOP 子句返回。命令 BY 子句不保证订购 查询视图时的结果, 除非 ORDER BY 在 查询本身。

                SQL Server 2005 breaking changes

                希望这会有所帮助, 帕特里克

                【讨论】:

                • TOP 100 PERCENT 不保证订购。谢谢 这解决了我的问题!
                【解决方案9】:

                对我来说,这个解决方案也很好用:

                SELECT tbl.a, tbl.b
                FROM (SELECT TOP (select count(1) FROM yourtable) a,b FROM yourtable order by a) tbl
                

                【讨论】:

                  【解决方案10】:

                  尝试将 order by 子句移到 sub select 之外并在 sub select 中添加 order by 字段

                  
                  
                  SELECT * FROM 
                  
                  (SELECT COUNT(1) ,refKlinik_id FROM Seanslar WHERE MONTH(tarihi) = 4 GROUP BY refKlinik_id)
                  as dorduncuay 
                  
                  ORDER BY refKlinik_id 
                  
                  

                  【讨论】:

                    【解决方案11】:

                    将 Top 命令添加到您的子查询...

                    SELECT 
                    (
                    SELECT TOP 100 PERCENT 
                        COUNT(1) 
                    FROM 
                        Seanslar 
                    WHERE 
                        MONTH(tarihi) = 4
                    GROUP BY 
                        refKlinik_id
                    ORDER BY 
                        refKlinik_id
                    ) as dorduncuay
                    

                    :)

                    【讨论】:

                      【解决方案12】:

                      您拥有的子查询(嵌套视图)会返回一个数据集,然后您可以在调用查询中对其进行排序。对子查询本身进行排序不会(可靠)改变调用查询中结果的顺序。

                      至于您的 SQL 本身: a) 当您返回单个值时,我认为没有理由订购。 b) 无论如何,我认为子查询没有任何理由,因为您只返回一个值。

                      我猜这里还有更多信息,您可能想告诉我们以解决您遇到的问题。

                      【讨论】:

                        【解决方案13】:

                        这是你得到的错误(强调我的):

                        ORDER BY 子句在 视图,内联函数,派生 表、子查询和公用表 表达式,除非 TOP 或 FOR XML 是 也指定了。

                        那么,如何避免错误呢?通过指定 TOP,我猜是一种可能性。

                        SELECT (
                          SELECT TOP 100 PERCENT
                          COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
                          GROUP BY refKlinik_id
                          ORDER BY refKlinik_id
                        ) as dorduncuay
                        

                        【讨论】:

                        • 这不是按顺序排列的,如果您指定 top 99.99999 Percent 它会按预期工作
                        • @foz1284 您能否指出一些证实此声明的文档或参考资料?
                        • blogs.msdn.com/b/queryoptteam/archive/2006/03/24/560396.aspx 如此处解释的 TOP 100 Percent 没有顺序,因为它保证返回所有悬停在 SQL Server 评估前 99 的行时,它需要执行顺序以确保它返回正确的行。
                        • 据我了解,这种特性只影响没有聚集索引的表,所以在使用TOP 100 PERCENT 时不会遇到一般问题。不过谢谢你的提示,我不知道。
                        • 我刚刚快速重读了一遍,我看到了您所引用的内容,前几天我正在订购一个将 3 个表联合在一起的子查询,这对我来说是个问题(我m 不是 SQL 专家,但我猜结果应该没有聚集索引!)
                        【解决方案14】:

                        在此示例中,排序不添加任何信息 - 集合的 COUNT 与它的顺序相同!

                        如果您选择的东西 确实 取决于顺序,您需要执行错误消息告诉您的事情之一 - 使用 TOP 或 FOR XML

                        【讨论】:

                          【解决方案15】:

                          您不需要在子查询中进行排序。将其移出到主查询中,并在子查询中包含您要排序的列。

                          但是,您的查询只是返回一个计数,所以我看不到 order by。

                          【讨论】:

                            猜你喜欢
                            • 2016-04-29
                            • 1970-01-01
                            • 1970-01-01
                            • 2020-06-23
                            • 1970-01-01
                            • 2019-01-21
                            • 1970-01-01
                            • 2011-04-10
                            • 1970-01-01
                            相关资源
                            最近更新 更多