【问题标题】:When Select distinct From Features give Error ORDER BY items must appear in the select list?当 Select distinct From Features 给出错误 ORDER BY 项目必须出现在选择列表中?
【发布时间】:2020-10-12 04:33:50
【问题描述】:

我在处理 SQL Server 2012 查询时遇到问题:

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

请问这个问题怎么解决?

在我的解决方案中,我在 DkFeatureName 中重复了更多功能,因此我只需要选择不同的。

功能,这将防止重复列。

create table #nonparametricdata
(
    PART_ID nvarchar(50) ,
    CompanyName  nvarchar(50),
    PartNumber nvarchar(50),
    DKFeatureName nvarchar(100),
    Tempvalue nvarchar(50),
    StatusId int,
    DisplayOrder int,
    FlagAllow bit
)

insert into #nonparametricdata
values
('1222','Honda','silicon','package','15.50Am',3,4,0),
('1900','MERCEIS','GLASS','family','90.00Am',2,3,1),
('5000','TOYOTA','alominia','source','70.20kg',3,5,0),
('8000','MACDA','motor','parametric','50.40kg',2,1,1),
('8900','JEB','mirror','noparametric','75.35kg',2,6,0),
('8000','MACDA','motor','parametric','50.40kg',2,2,1)

DECLARE @Header NVARCHAR(MAX)
SELECT
    @Header = STUFF(
        (
            SELECT distinct ', ' +  case when A.splitFlag = 1 then ''''+A.DKFeatureName +''' as '''+A.DKFeatureName+''','''+ A.DKFeatureName + 'Units'  +''' as ''' + A.DKFeatureName +'Units' +'''' else ''''+A.DKFeatureName +''' as ''' + A.DKFeatureName +''''    end
            FROM #FinalTable A
            where StatusId=2
        
            ORDER BY DisplayOrder
            FOR XML PATH ('')
        ),1,2,''
    )
    SELECT @Header

【问题讨论】:

  • 能否请您出示您的预期结果。
  • 您的示例 SQL 不可执行。 #FinalTable没有定义
  • 如果该列未出现在distinct 的选择列表中,这可能意味着有 2 或更多 行被压缩为单个输出行和它们可以有不同的DisplayOrder - 服务器非常正确地告诉你它不知道如何对这样的行进行排序。

标签: sql-server select stored-procedures sql-server-2012 dynamic-sql


【解决方案1】:

不要使用 DISTINCT,而是使用 GROUP BY 子句。这允许您按聚合的缺失列排序。原理

SELECT A, B
GROUP BY A, B
ORDER BY MAX(C)

或者干脆按照错误信息的提示去做:在选择列表中包含DisplayOrder

SELECT distinct DisplayOrder, ', ' +  case when A.splitFlag = 1 then ''''+A.DKFeatureName ...

问题是 DISTINCT 可能会丢弃一些行。因此,如果DisplayOrder 在这些其他相等的行中不同,那么应该使用其中哪一个进行排序?使用 GROUP BY,您可以指定哪一个。在我的示例中,它将是 MAX(DisplayOrder),即在其他不同的行中最大的。也可以是MIN()AVG() 或其他。

【讨论】:

    【解决方案2】:

    就错误消息而言,我会说这条消息几乎是不言自明的。要解释为什么会出现这种情况,请考虑以下数据:

    Name        DisplayOrder
    -----------------------------
    Name 1          1
    Name 1          4
    Name 2          3
    Name 2          2
    

    然后我们想要不同的名字,按DisplayOrder排序:

    SELECT DISTINCT Name
    FROM T
    ORDER BY DisplayOrder
    

    由于每个名字有两个DisplayOrder值,SQL Server不知道选择哪个,选择哪个会影响结果的顺序,所以必须告诉它哪个一个来挑选。

    我通常会将DISTINCT 换成GROUP BY 并使用聚合:

    SELECT Name
    FROM T
    GROUP BY Name
    ORDER BY MIN(DisplayOrder);
    

    在你的情况下,我认为你最终会得到类似的结果:

    DECLARE @Header NVARCHAR(MAX)
    SELECT
        @Header = STUFF(
            (
                SELECT ', ' +  case when A.splitFlag = 1 then ''''+A.DKFeatureName +''' as '''+A.DKFeatureName+''','''+ A.DKFeatureName + 'Units'  +''' as ''' + A.DKFeatureName +'Units' +'''' else ''''+A.DKFeatureName +''' as ''' + A.DKFeatureName +''''    end
                FROM #FinalTable A
                where StatusId=2
                GROUP BY A.SplitFlag, A.DKFeatureName
                ORDER BY MIN(DisplayOrder)
                FOR XML PATH ('')
            ),1,2,''
        )
        SELECT @Header
        
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多