子查询中的Order By的SQL错误

时间:2009-06-12 09:56:36

标签: sql-server sql-order-by

我正在使用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

15 个答案:

答案 0 :(得分:97)

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

  

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

答案 1 :(得分:33)

除了订单在您的查询中似乎没有意义的事实.... 要在子选择中使用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

希望这有帮助, 帕特里克

答案 2 :(得分:14)

如果您正在使用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

答案 3 :(得分:4)

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

但是,您的查询只是返回一个计数,所以我没有看到订单的重点。

答案 4 :(得分: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

<强>:)

答案 5 :(得分: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排序的内部子查询(可以是你的表中的任何一个)

答案 6 :(得分:2)

在这个例子中,order不添加任何信息 - 一个集合的COUNT是相同的顺序!

如果您选择依赖于订单的内容,则需要执行错误消息告诉您的事情之一 - 使用TOP或FOR XML

答案 7 :(得分:2)

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

至于你的SQL本身: a)由于您返回单个值,因此我没有看到订单的原因。 b)我认为没有理由进行子查询,因为你只返回一个值。

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

答案 8 :(得分:1)

尝试在子选择之外移动order by子句,并在子选择

中添加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 

答案 9 :(得分:1)

对我来说,这个解决方案也可以正常工作:

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

答案 10 :(得分:1)

If building a temp table, move the ORDER BY clause from inside the temp table code block to the outside.

Not allowed:

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

Allowed:

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

答案 11 :(得分:1)

美好的一天

对于某些人来说,子查询中的顺序令人怀疑。 如果您需要基于某种排序删除一些记录,则必须使用子查询中的排序。 像

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

,以便您可以删除最后一个插入表单表。 实际有三种删除方法。

但是,在许多情况下都可以使用子查询中的排序。

有关在链接下面的子查询中使用order by的删除方法

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

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

答案 12 :(得分:0)

我使用此代码获得最高工资

我也得到错误

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

前100名我用来避免错误

选择*来自( 选择tbl.Coloumn1,CONVERT(varchar,ROW_NUMBER()OVER(ORDER BY(SELECT 1)))AS Rowno from( 从Table1中选择前100名 *  由Coloumn1 desc)命令为tbl)为tbl,其中tbl.Rowno = 2

答案 13 :(得分:0)

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

-我希望费用表中的行的updatedate等于最大updatedate:

    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。

答案 14 :(得分: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

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