76

我正在使用 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在子查询中使用?

4

15 回答 15

118

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

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
于 2009-06-12T10:02:38.570 回答
37

除了 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 子句返回的行。ORDER BY 子句不保证查询视图时的有序结果,除非在查询本身中也指定了 ORDER BY。

请参阅SQL Server 2005 重大更改

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

于 2010-03-13T04:49:14.920 回答
33

如果您使用的是 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
于 2017-05-19T09:38:49.893 回答
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;
于 2016-10-20T20:10:12.197 回答
5

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

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

于 2009-06-12T09:58:56.830 回答
3

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

至于您的 SQL 本身:a)我没有看到 order by 因为您返回单个值的理由。b)无论如何,我认为没有理由进行子查询,因为您只返回一个值。

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

于 2009-06-12T10:03:19.147 回答
3

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

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

:)

于 2009-06-12T10:04:32.950 回答
3

也许这个技巧会帮助某人

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 排序的内部子查询(可以是您表中的任何一个)

于 2010-11-18T07:05:40.747 回答
2

在此示例中,排序不添加任何信息 - 无论其顺序如何,集合的 COUNT 都是相同的!

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

于 2009-06-12T09:59:05.537 回答
2

尝试将 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 

于 2012-09-24T02:07:48.677 回答
1

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

SELECT tbl.a, tbl.b
FROM (SELECT TOP (select count(1) FROM yourtable) a,b FROM yourtable order by a) tbl
于 2013-09-14T22:39:25.453 回答
1

再会

对于某些人来说,子查询中的顺序是有问题的。如果您需要基于某些排序删除某些记录,则必须使用子查询中的 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

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

于 2018-12-02T08:36:06.063 回答
0

我使用此代码获得最高薪水

我也得到错误喜欢

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

我用来避免错误的 TOP 100

select * from (select tbl.Coloumn1 ,CONVERT(varchar, ROW_NUMBER() OVER (ORDER BY (SELECT 1))) AS Rowno from (select top 100 * from Table1 order by Coloumn1 desc) as tbl) as tbl where tbl.Rowno =2

于 2018-02-22T06:12:17.713 回答
0

对于像 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。

于 2019-02-13T19:46:53.180 回答
0

当您有 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

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

于 2019-05-08T09:21:20.243 回答