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


Я добавил столбцы в списке выбора в список order by, но он по-прежнему дает мне ошибку:

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

вот сохраненный proc:

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 53

6 ответов:

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

ORDER BY 1, 2

или

ORDER BY rsc.RadioServiceCodeId, rsc.RadioServiceCode + ' - ' + rsc.RadioService

хотя они не одно и то же, в одном смысле DISTINCT подразумевает группу 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, элемент distinct директива can только применяется к окончательные результаты расчета: он больше ничего не знает об источнике расчета.

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

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

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

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

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

    заказать по RadioServiceCodeId, RadioService

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

    ЗАКАЗАТЬ ПО 1,2

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

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

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

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

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

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

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