Ошибка SQL с порядком в подзапросе

Я работаю с 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 в подзапросе?


person cagin    schedule 12.06.2009    source источник


Ответы (15)


Это ошибка, которую вы получаете (выделено мной):

Предложение 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
person Tomalak    schedule 12.06.2009
comment
это не упорядочивается, если вы укажете верхний процент 99,99999, он работает как положено - person foz1284; 03.07.2013
comment
@ foz1284 Можете ли вы указать на какую-нибудь документацию или ссылку, подтверждающую это утверждение? - person Tomalak; 03.07.2013
comment
blogs.msdn.com/b/queryoptteam/archive/ 2006/03/24/560396.aspx как объяснено здесь, с TOP 100 Percent нет порядка, поскольку он гарантированно возвращает все строки, когда SQL Server оценивает верхние 99, он должен выполнить заказ, чтобы убедиться, что это возвращает правильные строки. - person foz1284; 05.07.2013
comment
Насколько я понимаю, эта особенность влияет только на таблицы без кластеризованного индекса, так что это не общая проблема, с которой вы столкнетесь при использовании TOP 100 PERCENT. Но спасибо за подсказку, я этого не знал. - person Tomalak; 05.07.2013
comment
я только что быстро перечитал, и я вижу, на что вы ссылаетесь. На днях это было проблемой для меня, когда я заказывал подзапрос, который объединял 3 таблицы вместе (я не эксперт по SQL, но я предполагаю, что результат не будет иметь кластеризованного индекса!) - person foz1284; 05.07.2013
comment
@ foz1284 Привет, ссылка не найдена. Не могли бы вы обновить новую ссылку? Спасибо. - person fish-404; 23.03.2021

Помимо того факта, что порядок в вашем запросе не имеет смысла.... Чтобы использовать порядок в подзапросе, вам нужно будет использовать 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.

Надеюсь, это поможет, Патрик.

person Patrick Wolf    schedule 13.03.2010
comment
TOP 100 PERCENT не гарантирует заказ. Спасибо Это решило мою проблему! - person Matt Klepeis; 09.02.2011

Если вы работаете с 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
person Jez    schedule 19.05.2017
comment
Из всех ответов, которые я искал за последние 20 минут, это был единственный, который решил мою проблему. - person iminiki; 21.07.2019
comment
Я избегал этого ответа, потому что он кажется таким избыточным и бессмысленным, наверняка был бы лучший способ заставить его работать! .... нет. Так вот он, это ответ вам всем. Какая странная особенность. - person Jose V; 14.02.2020
comment
Я добавил пример использования ORDER BY в CTE SQL Server (временный именованный набор результатов) в ответ на другой вопрос здесь - person Jose V; 15.02.2020

При построении временной таблицы переместите предложение ORDER BY из блока кода временной таблицы наружу.

Запрещено:

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

Разрешено:

SELECT * FROM (
SELECT A FROM Y
) X
ORDER BY X.A;
person MacGyver    schedule 20.10.2016

Вам не нужен порядок в вашем подзапросе. Переместите его в основной запрос и включите столбец, по которому вы хотите упорядочить, в подзапрос.

однако ваш запрос просто возвращает счетчик, поэтому я не вижу смысла в заказе.

person cjk    schedule 12.06.2009

Добавьте команду Top в свой подзапрос...

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

:)

person Community    schedule 12.06.2009

может этот трюк кому-то поможет

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 (может быть любым из вашей таблицы)

person Vlad    schedule 18.11.2010

В этом примере упорядочивание не добавляет никакой информации - СЧЕТЧИК набора один и тот же, в каком бы порядке он ни находился!

Если бы вы выбирали что-то, что зависело от порядка, вам нужно было бы сделать одну из вещей, о которых вам сообщает сообщение об ошибке, — использовать TOP или FOR XML.

person AakashM    schedule 12.06.2009

Подзапрос (вложенное представление) в том виде, в каком он у вас есть, возвращает набор данных, который вы затем можете упорядочить в вызывающем запросе. Порядок самого подзапроса не будет (надежно) влиять на порядок результатов в вызывающем запросе.

Что касается самого вашего SQL: а) я не вижу причин для заказа, поскольку вы возвращаете одно значение. б) В любом случае я не вижу причин для подзапроса, поскольку вы возвращаете только одно значение.

Я предполагаю, что здесь есть гораздо больше информации, которую вы, возможно, захотите сообщить нам, чтобы решить проблему, с которой вы столкнулись.

person Robin Day    schedule 12.06.2009

Попробуйте переместить порядок по предложению за пределы подвыборки и добавить порядок по полю в подвыборке



SELECT * FROM 

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

ORDER BY refKlinik_id 

person indrap    schedule 24.09.2012

Для меня это решение также отлично работает:

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

Добрый день

для некоторых парней порядок в подзапросе сомнителен. порядок в подзапросе необходимо использовать, если вам нужно удалить некоторые записи на основе некоторой сортировки. как

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

так что вы можете удалить последнюю таблицу формы вставки. на самом деле есть три способа сделать это удаление.

однако во многих случаях можно использовать порядок в подзапросе.

для методов удаления, которые используют порядок в обзоре подзапроса по ссылке ниже

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

Я надеюсь, что это помогает. Спасибо вам всем

person Omar Kamel    schedule 02.12.2018

Я использую этот код, чтобы получить вторую самую высокую зарплату

Я также получаю сообщение об ошибке

Предложение ORDER BY недопустимо в представлениях, встроенных функциях, производных таблицах, подзапросах и общих табличных выражениях, если также не указано TOP или FOR XML.

ТОП-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 ) как tbl, где tbl.Rowno=2

person soundar rajan    schedule 22.02.2018

Для простого подсчета, как показывает 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. Это похоже на хак:

    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.

person iLWR    schedule 13.02.2019

На возможные потребности заказать подзапрос, когда у вас есть 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

Я думаю, что это более понятно, чем фальшивый результат подзапроса.

person iguypouf    schedule 08.05.2019