Почему SQL Server 2008 заказывает при использовании GROUP BY, а порядок не указан? - PullRequest
4 голосов
/ 15 октября 2010

У меня очень странная проблема, которой я пока не нашел объяснения. В SQL Server 2008 и с использованием GROUP BY он упорядочивает мои столбцы без указания ORDER BY. Вот скрипт, который демонстрирует ситуацию.

CREATE TABLE #Values ( FieldValue varchar(50) )

;WITH FieldValues AS
(
    SELECT '4' FieldValue UNION ALL
    SELECT '3' FieldValue UNION ALL
    SELECT '2' FieldValue UNION ALL
    SELECT '1' FieldValue
)
INSERT INTO #Values ( FieldValue )
SELECT
    FieldValue 
FROM FieldValues

-- First SELECT demonstrating they are ordered DESCENDING
SELECT
    FieldValue
FROM #Values

-- Second SELECT demonstrating they are ordered ASCENDING
SELECT
    FieldValue
FROM #Values
GROUP BY
    FieldValue

DROP TABLE #Values

Первый SELECT вернет

4
3
2
1

Второй SELECT вернет

1
2
3
4

В соответствии с Документацией MSDN говорится: " Предложение GROUP BY не упорядочивает набор результатов "

Ответы [ 4 ]

13 голосов
/ 15 октября 2010

Чтобы ответить на этот вопрос, посмотрите на планы запросов, разработанные обоими.

Первый SELECT - это простое сканирование таблицы, что означает, что он создает строки в порядке размещения. Поскольку это новая таблица, она соответствует порядку, в который вы вставили записи.

Второй SELECT добавляет GROUP BY, который SQL Server реализует с помощью особой сортировки, поскольку предполагаемое количество строк очень мало. Если вам нужно больше строк или добавить агрегат в ваш SELECT, этот оператор может измениться.

Например, попробуйте:

CREATE TABLE #Values ( FieldValue varchar(50) )

;WITH FieldValues AS
(
    SELECT '4' FieldValue UNION ALL
    SELECT '3' FieldValue UNION ALL
    SELECT '2' FieldValue UNION ALL
    SELECT '1' FieldValue
)
INSERT INTO #Values ( FieldValue )
SELECT
    A.FieldValue
FROM FieldValues A
CROSS JOIN FieldValues B
CROSS JOIN FieldValues C
CROSS JOIN FieldValues D
CROSS JOIN FieldValues E
CROSS JOIN FieldValues F

SELECT
    FieldValue
FROM #Values
GROUP BY
    FieldValue

DROP TABLE #Values

Из-за количества строк это превращается в агрегат хэшей, и теперь в плане запроса сортировка отсутствует.

Без ORDER BY SQL Server может возвращать результаты в любом порядке, и порядок, в котором он возвращается, является побочным эффектом того, как он считает, что он может наиболее быстро вернуть данные.

6 голосов
/ 15 октября 2010

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

Возможно, в вашем конкретном запросе он вернет упорядоченные результаты, но это не значит, что он будет всегда сортировать resltsets при использовании предложения group by.

Может быть (просто возможно) он использует какой-то агрегат хеша для вычисления группы, и хеш-таблица сортируется по 1,2,3,4.И затем я возвращаю строки в порядке хеширования ...

1 голос
/ 15 октября 2010

Здесь вы также можете убрать свои операторы вставки. В SQL Server 2008 добавлена ​​новая функция для вставок. Пример:

Инертный в тбл (клмн) Значения (1), (2), (3) Каждая запись не нуждается в собственном операторе вставки, и каждая разделяется комой

1 голос
/ 15 октября 2010

Это аспект оптимизации БД.Как правило, SQL Engine должен анализировать данные в порядке сгруппированного столбца.Вместо того, чтобы тратить время впустую, он оставляет набор данных в любом разобранном порядке.

Бывают ситуации, когда этого не происходит (особенно если используются агрегатные функции).Использование команды ORDER BY, очевидно, переопределяет эту функциональность (и, следовательно, подразумевает незначительную дополнительную нагрузку, которой недостаточно для беспокойства во всех случаях, кроме самых крайних).

...