如果指定了SELECT DISTINCT,则ORDER BY项目必须出现在选择列表中


73

我将选择列表中的列添加到按列表排序,但是它仍然给我错误:

如果指定了SELECT DISTINCT,则ORDER BY项目必须出现在选择列表中。

这是存储的过程:

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

Answers:


65

尝试这个:

ORDER BY 1, 2

要么

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

12
扩展其原因可能是一个好主意-尤其是在计算字段中使用时未明确标识列的事实。
Mike Burton,

7
对snytax ORDER BY 1、2的功能感到好奇。
Xaisoft

按1、2的顺序在SQL Server中为我工作。1,2,3,...基本上是select [1,2,3]语句中使用的列的基于1的索引。那就是我得到的。
Hammad Khan

1
我不明白这个答案。请解释更多。
alansiqueira27 2014年

58

尽管它们不是一回事,但从某种意义上讲,DISTINCTGROUP 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伪指令只能应用于计算的最终结果:它不再对计算源一无所知。

这意味着服务器并不真正知道它可以再依赖那些列了。它知道使用了它们,但是不知道计算操作是否会导致类似于我上面第一个简单示例的效果。

因此,现在您需要执行其他操作来告诉服务器可以使用这些列进行排序。有几种方法可以做到这一点,但是这种方法应该可以:

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

3
Distinct只是意味着消除重复项,一旦完成,就要对结果中的不同行进行排序是有意义的
Charles Bretana

1
查尔斯,我想您没能说清楚,但我对此帖子做了一些澄清。
Joel Coehoorn

15

尝试以下方法之一:

  1. 使用列别名:

    ORDER BY RadioServiceCodeId,RadioService

  2. 使用栏位置:

    按1,2订购

您只能按实际显示在DISTINCT查询结果中的列进行排序-基础数据不可用于排序。


3

定义串联时,如果要对新列进行排序,则需要对它使用ALIAS,并结合使用DISTINCT Some 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

3

Distinct和Group By通常出于不同的目的执行相同的操作...它们都基于正在分组的列(或在Select Distinct子句中选择的列)在内存中创建“工作”表-然后填充查询读取数据的工作表,仅在值指示需要这样做时才添加新的“行” ...

唯一的区别在于,“分组依据”中的工作表中还包含其他“列”,用于任何计算出的聚合字段,例如Sum(),Count(),Avg()等,需要为每个读取的原始行进行更新。区别不必这样做...在特殊情况下,如果仅按分组依据来获取不同的值(并且输出中没有聚合列),则它可能是完全相同的查询计划...。查看两个选项的查询执行计划并查看其效果将非常有趣...

如果您正在这样做,那么一定要采用可读性的方法(当您的目的是消除重复的行,并且您不计算任何聚合列时)


-1

您可以尝试子查询:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.