子查询中的 Order By 的 SQL 错误

Posted

技术标签:

【中文标题】子查询中的 Order By 的 SQL 错误【英文标题】:SQL Error with Order By in Subquery 【发布时间】: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

【问题讨论】:

【参考方案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。

【讨论】:

以上是关于子查询中的 Order By 的 SQL 错误的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 查询错误 -ORDER BY 子句在视图中无效

SQL Server查询错误-ORDER BY子句在视图中无效

子查询中不允许用order by子句,那么应该怎么办?

sql子查询 order by失效问题

当子查询内存在ORDER BY 字句时查询会报错

oracle中在in子查询语句中order by排序能否用?