Элементы ORDER BY должны отображаться в списке выбора, если указан параметр SELECT DISTINCT - PullRequest
58 голосов
/ 05 ноября 2008

Я добавил столбцы в списке выбора в список по порядку, но все равно выдает ошибку:

Элементы ORDER BY должны отображаться в списке выбора, если указано SELECT DISTINCT.

Вот хранимый процесс:

CREATE PROCEDURE [dbo].[GetRadioServiceCodesINGroup] 
@RadioServiceGroup nvarchar(1000) = NULL
AS
BEGIN
SET NOCOUNT ON;

SELECT DISTINCT rsc.RadioServiceCodeId,
                rsc.RadioServiceCode + ' - ' + rsc.RadioService as RadioService
FROM sbi_l_radioservicecodes rsc
INNER JOIN sbi_l_radioservicecodegroups rscg 
ON rsc.radioservicecodeid = rscg.radioservicecodeid
WHERE rscg.radioservicegroupid IN 
(select val from dbo.fnParseArray(@RadioServiceGroup,','))
OR @RadioServiceGroup IS NULL  
ORDER BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService

END

Ответы [ 6 ]

54 голосов
/ 05 ноября 2008

Попробуйте это:

ORDER BY 1, 2

OR

ORDER BY rsc.RadioServiceCodeId, rsc.RadioServiceCode + ' - ' + rsc.RadioService
44 голосов
/ 05 ноября 2008

Хотя это не одно и то же, в некотором смысле DISTINCT подразумевает GROUP BY, потому что каждый DISTINCT может быть переписан с использованием GROUP BY. Имея это в виду, не имеет смысла заказывать что-то, чего нет в совокупной группе.

Например, если у вас есть такая таблица:

col1  col2
----  ----
 1     1
 1     2
 2     1
 2     2
 2     3
 3     1

, а затем попробуйте запросить его так:

SELECT DISTINCT col1 FROM [table] WHERE col2 > 2 ORDER BY col1, col2

Это не имеет смысла, потому что может в конечном итоге быть несколькими значениями col2 в строке. Какой из них следует использовать для заказа? Конечно, в этом запросе вы знаете, что результаты не будут такими, но сервер базы данных не может знать об этом заранее.

Теперь ваш случай немного отличается. Вы включили все столбцы из предложения order by в предложение select, и поэтому на первый взгляд может показаться, что все они сгруппированы. Однако некоторые из этих столбцов были включены в вычисляемое поле. Когда вы делаете это в сочетании с различными, директива distinct может только применяться к окончательным результатам вычисления: она ничего не знает об источнике вычисления больше.

Это означает, что сервер на самом деле не знает, что может больше рассчитывать на эти столбцы. Он знает, что они были использованы, но не знает, может ли операция вычисления вызвать эффект, подобный моему первому простому примеру выше.

Так что теперь вам нужно сделать что-то еще, чтобы сообщить серверу, что столбцы можно использовать для заказа. Есть несколько способов сделать это, но этот подход должен работать хорошо:

SELECT rsc.RadioServiceCodeId,
            rsc.RadioServiceCode + ' - ' + rsc.RadioService as RadioService
FROM sbi_l_radioservicecodes rsc
INNER JOIN sbi_l_radioservicecodegroups rscg 
    ON rsc.radioservicecodeid = rscg.radioservicecodeid
WHERE rscg.radioservicegroupid IN 
    (SELECT val FROM dbo.fnParseArray(@RadioServiceGroup,','))
    OR @RadioServiceGroup IS NULL  
GROUP BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService
ORDER BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService
10 голосов
/ 05 ноября 2008

Попробуйте один из них:

  1. Использовать псевдоним столбца:

    ЗАКАЗ ПО RadioServiceCodeId, RadioService

  2. Использовать позицию столбца:

    ЗАКАЗАТЬ НА 1,2

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

3 голосов
/ 05 ноября 2008

Distinct и Group By обычно делают одно и то же для разных целей ... Они оба создают «рабочую» таблицу в памяти на основе столбцов, по которым группируются (или выбираются в предложении Select Distinct) - и затем заполните эту рабочую таблицу, когда запрос читает данные, добавляя новую «строку», только когда значения указывают на необходимость сделать это ...

Единственное отличие состоит в том, что в Group By есть дополнительные «столбцы» в рабочей таблице для любых вычисляемых агрегированных полей, таких как Sum (), Count (), Avg () и т. Д., Которые необходимо обновить для каждого оригинала. строка прочитана. Distinct не обязан это делать ... В особом случае, когда вы группируете By только для того, чтобы получить разные значения (и в выводе нет агрегированных столбцов), тогда это, вероятно, точно такой же план запроса .... было бы интересно просмотреть план выполнения запроса для двух вариантов и посмотреть, что он сделал ...

Конечно, отличным является способ достижения читабельности, если вы этим занимаетесь (когда ваша цель - исключить дублирующиеся строки, а вы не вычисляете какие-либо статистические столбцы)

2 голосов
/ 02 июля 2012

Когда вы определяете конкатенацию, вам нужно использовать ALIAS для нового столбца, если вы хотите заказать его в сочетании с DISTINCT. Некоторые Ex с sql 2008

--this works 

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) as FullName 
    from SalesLT.Customer c 
    order by FullName

--this works too

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) 
    from SalesLT.Customer c 
    order by 1

-- this doesn't 

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) as FullName 
    from SalesLT.Customer c 
    order by c.FirstName, c.LastName

-- the problem the DISTINCT needs an order on the new concatenated column, here I order on the singular column
-- this works

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) 
        as FullName, CustomerID 
        from SalesLT.Customer c 

order by 1, CustomerID

-- this doesn't

    SELECT DISTINCT (c.FirstName + ' ' + c.LastName) as FullName 
     from SalesLT.Customer c 
      order by 1, CustomerID
0 голосов
/ 10 ноября 2015

Вы можете попробовать подзапрос:

SELECT DISTINCT TEST.* FROM (
    SELECT rsc.RadioServiceCodeId,
        rsc.RadioServiceCode + ' - ' + rsc.RadioService as RadioService
    FROM sbi_l_radioservicecodes rsc
       INNER JOIN sbi_l_radioservicecodegroups rscg ON  rsc.radioservicecodeid = rscg.radioservicecodeid
    WHERE rscg.radioservicegroupid IN 
       (select val from dbo.fnParseArray(@RadioServiceGroup,','))
        OR @RadioServiceGroup IS NULL  
    ORDER BY rsc.RadioServiceCode,rsc.RadioServiceCodeId,rsc.RadioService
) as TEST
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...