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

我将select列表中的列添加到按列表sorting,但它仍然给我错误:

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

这里是存储过程:

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 

尝试这个:

 ORDER BY 1, 2 

要么

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

虽然它们不是同一个东西,但从某种意义上说,DISTINCT意味着一个GROUP BY,因为每个DISTINCT都可以用GROUP BY来重写。 考虑到这一点,通过不在聚合组中的东西来sorting是没有意义的。

例如,如果你有这样一个表:

 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值。 该订单使用哪一个? 当然,在这个查询中你知道结果不会那样,但是数据库服务器不能提前知道。

现在,你的情况有点不一样了。 您在select子句中包含了order by子句中的所有列,因此乍一看它们都是分组的。 然而,其中一些列被包括在计算字段中。 当你把它和不同的指令结合起来的时候, distinct指令只能用于计算的最终结果 :它不再了解计算的来源。

这意味着服务器不知道它可以指望这些列了。 它知道它们已被使用,但不知道计算操作是否会导致类似于上面第一个简单示例的效果。

所以现在你需要做别的事情来告诉服务器列可以用来sorting。 有几种方法可以做到这一点,但是这种方法应该可行:

 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. 使用列别名:

    ORDER BY RadioServiceCodeId,RadioService

  2. 使用列位置:

    ORDER BY 1,2

您只能按实际出现在DISTINCT查询结果中的列进行sorting – 基础数据不可用于sorting。

当你定义连接你需要使用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 

独特和分组通常做同样的事情,出于不同的目的…他们都在内存中创build一个“工作”的表,基于分组的列(或在select差异子句中select) – 然后填充工作表作为查询读取数据,添加一个新的“行”只有当值表明需要这样做…

唯一的区别是,在Group By中,对于任何计算的聚合字段,如Sum(),Count(),Avg()等,工作表中还有额外的“列”,需要为每个原始行读取更新。 独特不必这样做…在特殊情况下,你只是为了得到不同的值,(并没有在输出聚合列),那么它可能是完全相同的查询计划….它查看这两个选项的查询执行计划并查看它做了什么会很有趣。

当然,如果这是你正在做的(当你的目的是消除重复的行,而你不计算任何聚合列)

你可以尝试一个子查询:

 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