【问题标题】:SQL Server : the ORDER BY clause is invalid in views, inline functions, derived tables, subqueriesSQL Server:ORDER BY 子句在视图、内联函数、派生表、子查询中无效
【发布时间】:2017-01-07 07:09:35
【问题描述】:

我在存储过程中有这个查询):

SELECT *
FROM   
    dbo.JointHistory c
OUTER APPLY
    (SELECT 
         MAX(CASE NdtType WHEN 'RT' THEN RequestNumber END) AS MasterRTRequestNumber,
         MAX(CASE NdtType WHEN 'RT' THEN NdtReportNumber END) AS ContractorRTRequestNumber,
         MAX(CASE NdtType WHEN 'RT' THEN ResponseReportNumber END) AS ContractorRTReportNumber,
         MAX(CASE NdtType WHEN 'RT' THEN ResponseReportDatetime END) AS RTDate,
         MAX(CASE NdtType WHEN 'RT' THEN Defect END) AS RTDefect,
         MAX(CASE NdtType WHEN 'RT' THEN Remark END) AS RTSegment,
         MAX(CASE NdtType WHEN 'PT' THEN RequestNumber END) AS MasterPTRequestNumber,
         MAX(CASE NdtType WHEN 'PT' THEN NdtReportNumber END) AS ContractorPTRequestNumber,
         MAX(CASE NdtType WHEN 'PT' THEN ResponseReportNumber END) AS ContractorPTReportNumber,
         MAX(CASE NdtType WHEN 'PT' THEN ResponseReportDatetime END) AS PTDate,
         MAX(CASE NdtType WHEN 'PT' THEN Defect END) AS PTDefect,
         MAX(CASE NdtType WHEN 'PT' THEN Remark END) AS PTSegment,
         MAX(CASE NdtType WHEN 'PWHT' THEN RequestNumber END) AS MasterPWHTRequestNumber,
         MAX(CASE NdtType WHEN 'PWHT' THEN NdtReportNumber END) AS ContractorPWHTRequestNumber,
         MAX(CASE NdtType WHEN 'PWHT' THEN ResponseReportNumber END) AS ContractorPWHTReportNumber,
         MAX(CASE NdtType WHEN 'PWHT' THEN ResponseReportDatetime END) AS PWHTDate,
         MAX(CASE NdtType WHEN 'PWHT' THEN Defect END) AS PWHTDefect,
         MAX(CASE NdtType WHEN 'PWHT' THEN Remark END) AS PWHTSegment,
         MAX(CASE NdtType WHEN 'MT' THEN RequestNumber END) AS MasterMTRequestNumber,
         MAX(CASE NdtType WHEN 'MT' THEN NdtReportNumber END) AS ContractorMTRequestNumber,
         MAX(CASE NdtType WHEN 'MT' THEN ResponseReportNumber END) AS ContractorMTReportNumber,
         MAX(CASE NdtType WHEN 'MT' THEN ResponseReportDatetime END) AS MTDate,
         MAX(CASE NdtType WHEN 'MT' THEN Defect END) AS MTDefect,
         MAX(CASE NdtType WHEN 'MT' THEN Remark END) AS MTSegment,
         MAX(CASE NdtType WHEN 'UT' THEN RequestNumber END) AS MasterUTRequestNumber,
         MAX(CASE NdtType WHEN 'UT' THEN NdtReportNumber END) AS ContractorUTRequestNumber,
         MAX(CASE NdtType WHEN 'UT' THEN ResponseReportNumber END) AS ContractorUTReportNumber,
         MAX(CASE NdtType WHEN 'UT' THEN ResponseReportDatetime END) AS UTDate,
         MAX(CASE NdtType WHEN 'UT' THEN Defect END) AS UTDefect,
         MAX(CASE NdtType WHEN 'UT' THEN Remark END) AS UTSegment
     FROM   
         (SELECT TOP 1 WITH TIES 
              NRD.NdtType, NRD.RequestNumber, NR.NdtReportNumber,
              NRD.ResponseReportDatetime, NRD.Defect,
              NRD.ResponseReportNumber, NRD.Remark
          FROM   
              dbo.NdtReportDetails NRD
          LEFT OUTER JOIN 
              NdtReports NR ON NRD.ReportId = NR.Id
          WHERE  
              NRD.JointId = c.Id
              AND NRD.NdtType IN ( 'RT', 'PT', 'PWHT', 'MT', 'UT' )
          ORDER BY 
              NRD.Id DESC) i) b

但是基于这个问题:https://stackoverflow.com/questions/41518618/select-top-ties-in-sql-cant-return-expected-data/41518699查询结束有问题

所以我的查询变成了这样:

 SELECT *
FROM   dbo.JointHistory c
       OUTER Apply (SELECT Max(CASE NdtType WHEN 'RT' THEN RequestNumber END) AS MasterRTRequestNumber,
                           Max(CASE NdtType WHEN 'RT' THEN NdtReportNumber END) AS ContractorRTRequestNumber,
                           Max(CASE NdtType WHEN 'RT' THEN ResponseReportNumber END) AS ContractorRTReportNumber,
                           Max(CASE NdtType WHEN 'RT' THEN ResponseReportDatetime END) AS RTDate,
                           Max(CASE NdtType WHEN 'RT' THEN Defect END) AS RTDefect,
                           Max(CASE NdtType WHEN 'RT' THEN Remark END) AS RTSegment,

                           Max(CASE NdtType WHEN 'PT' THEN RequestNumber END) AS MasterPTRequestNumber,
                           Max(CASE NdtType WHEN 'PT' THEN NdtReportNumber END) AS ContractorPTRequestNumber,
                           Max(CASE NdtType WHEN 'PT' THEN ResponseReportNumber END) AS ContractorPTReportNumber,
                           Max(CASE NdtType WHEN 'PT' THEN ResponseReportDatetime END) AS PTDate,
                           Max(CASE NdtType WHEN 'PT' THEN Defect END) AS PTDefect,
                           Max(CASE NdtType WHEN 'PT' THEN Remark END) AS PTSegment,

                               Max(CASE NdtType WHEN 'PWHT' THEN RequestNumber END) AS MasterPWHTRequestNumber,
                           Max(CASE NdtType WHEN 'PWHT' THEN NdtReportNumber END) AS ContractorPWHTRequestNumber,
                           Max(CASE NdtType WHEN 'PWHT' THEN ResponseReportNumber END) AS ContractorPWHTReportNumber,
                           Max(CASE NdtType WHEN 'PWHT' THEN ResponseReportDatetime END) AS PWHTDate,
                           Max(CASE NdtType WHEN 'PWHT' THEN Defect END) AS PWHTDefect,
                           Max(CASE NdtType WHEN 'PWHT' THEN Remark END) AS PWHTSegment,

                                   Max(CASE NdtType WHEN 'MT' THEN RequestNumber END) AS MasterMTRequestNumber,
                           Max(CASE NdtType WHEN 'MT' THEN NdtReportNumber END) AS ContractorMTRequestNumber,
                           Max(CASE NdtType WHEN 'MT' THEN ResponseReportNumber END) AS ContractorMTReportNumber,
                           Max(CASE NdtType WHEN 'MT' THEN ResponseReportDatetime END) AS MTDate,
                           Max(CASE NdtType WHEN 'MT' THEN Defect END) AS MTDefect,
                           Max(CASE NdtType WHEN 'MT' THEN Remark END) AS MTSegment,

                                           Max(CASE NdtType WHEN 'UT' THEN RequestNumber END) AS MasterUTRequestNumber,
                           Max(CASE NdtType WHEN 'UT' THEN NdtReportNumber END) AS ContractorUTRequestNumber,
                           Max(CASE NdtType WHEN 'UT' THEN ResponseReportNumber END) AS ContractorUTReportNumber,
                           Max(CASE NdtType WHEN 'UT' THEN ResponseReportDatetime END) AS UTDate,
                           Max(CASE NdtType WHEN 'UT' THEN Defect END) AS UTDefect,
                           Max(CASE NdtType WHEN 'UT' THEN Remark END) AS UTSegment


                    FROM   (

SELECT t.NdtType,
       t.RequestNumber,
       t.NdtReportNumber,
       t.ResponseReportDatetime,
       t.Defect,
       t.ResponseReportNumber,
       t.Remark
FROM
(
    SELECT NRD.NdtType,
           NRD.Id,
           NRD.RequestNumber,
           NR.NdtReportNumber,
           NRD.ResponseReportDatetime,
           NRD.Defect,
           NRD.ResponseReportNumber,
           NRD.Remark,
           ROW_NUMBER() OVER(PARTITION BY NRD.NdtType ORDER BY NRD.Id DESC) AS rn
    FROM dbo.NdtReportDetails NRD
    LEFT OUTER JOIN NdtReports NR
        ON NRD.ReportId = NR.Id
    WHERE NRD.JointId = c.Id AND
          NRD.NdtType IN ('RT', 'PT', 'PWHT', 'MT', 'UT')
) t
WHERE t.rn = 1
ORDER BY t.Id DESC

) i)b

如您所见,查询结束是根据上述问题更改的,执行此查询后,我收到此错误:

消息 1033,级别 15,状态 1,过程 SPJointHistory,第 72 行
ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。

【问题讨论】:

  • 尝试将ORDER BY 移至外部选择。如果您考虑一下,在内部选择中使用 order by 是没有意义的,因为包装不一定遵守接收到的结果集的顺序。
  • 错误信息很清楚。您对其中的哪一部分有理解困难?
  • @KenWhite 我不知道该怎么做
  • 从子查询中删除 ORDER BY,这正是错误消息告诉您的内容。

标签: sql-server


【解决方案1】:

正如错误所说,您在内部查询中有一个ORDER BY。由于您没有显示id,我认为按id 排序没有任何意义。因此,您可以删除 order by 并将 INNER Query 转换为 CTE 并这样做:

;WITH ReportTable
AS(
   SELECT t.NdtType,
       t.RequestNumber,
       t.NdtReportNumber,
       t.ResponseReportDatetime,
       t.Defect,
       t.ResponseReportNumber,
       t.Remark
FROM
(
    SELECT NRD.NdtType,
           NRD.Id,
           NRD.RequestNumber,
           NR.NdtReportNumber,
           NRD.ResponseReportDatetime,
           NRD.Defect,
           NRD.ResponseReportNumber,
           NRD.Remark,
           ROW_NUMBER() OVER(PARTITION BY NRD.NdtType ORDER BY NRD.Id DESC) AS rn
    FROM dbo.NdtReportDetails NRD
    LEFT OUTER JOIN NdtReports NR
        ON NRD.ReportId = NR.Id
    WHERE NRD.JointId = c.Id AND
          NRD.NdtType IN ('RT', 'PT', 'PWHT', 'MT', 'UT')
) t
WHERE t.rn = 1
)


SELECT *
FROM   dbo.JointHistory c
       OUTER Apply (SELECT Max(CASE NdtType WHEN 'RT' THEN RequestNumber END) AS MasterRTRequestNumber,
                           Max(CASE NdtType WHEN 'RT' THEN NdtReportNumber END) AS ContractorRTRequestNumber,
                           Max(CASE NdtType WHEN 'RT' THEN ResponseReportNumber END) AS ContractorRTReportNumber,
                           Max(CASE NdtType WHEN 'RT' THEN ResponseReportDatetime END) AS RTDate,
                           Max(CASE NdtType WHEN 'RT' THEN Defect END) AS RTDefect,
                           Max(CASE NdtType WHEN 'RT' THEN Remark END) AS RTSegment,

                           Max(CASE NdtType WHEN 'PT' THEN RequestNumber END) AS MasterPTRequestNumber,
                           Max(CASE NdtType WHEN 'PT' THEN NdtReportNumber END) AS ContractorPTRequestNumber,
                           Max(CASE NdtType WHEN 'PT' THEN ResponseReportNumber END) AS ContractorPTReportNumber,
                           Max(CASE NdtType WHEN 'PT' THEN ResponseReportDatetime END) AS PTDate,
                           Max(CASE NdtType WHEN 'PT' THEN Defect END) AS PTDefect,
                           Max(CASE NdtType WHEN 'PT' THEN Remark END) AS PTSegment,

                               Max(CASE NdtType WHEN 'PWHT' THEN RequestNumber END) AS MasterPWHTRequestNumber,
                           Max(CASE NdtType WHEN 'PWHT' THEN NdtReportNumber END) AS ContractorPWHTRequestNumber,
                           Max(CASE NdtType WHEN 'PWHT' THEN ResponseReportNumber END) AS ContractorPWHTReportNumber,
                           Max(CASE NdtType WHEN 'PWHT' THEN ResponseReportDatetime END) AS PWHTDate,
                           Max(CASE NdtType WHEN 'PWHT' THEN Defect END) AS PWHTDefect,
                           Max(CASE NdtType WHEN 'PWHT' THEN Remark END) AS PWHTSegment,

                                   Max(CASE NdtType WHEN 'MT' THEN RequestNumber END) AS MasterMTRequestNumber,
                           Max(CASE NdtType WHEN 'MT' THEN NdtReportNumber END) AS ContractorMTRequestNumber,
                           Max(CASE NdtType WHEN 'MT' THEN ResponseReportNumber END) AS ContractorMTReportNumber,
                           Max(CASE NdtType WHEN 'MT' THEN ResponseReportDatetime END) AS MTDate,
                           Max(CASE NdtType WHEN 'MT' THEN Defect END) AS MTDefect,
                           Max(CASE NdtType WHEN 'MT' THEN Remark END) AS MTSegment,

                                           Max(CASE NdtType WHEN 'UT' THEN RequestNumber END) AS MasterUTRequestNumber,
                           Max(CASE NdtType WHEN 'UT' THEN NdtReportNumber END) AS ContractorUTRequestNumber,
                           Max(CASE NdtType WHEN 'UT' THEN ResponseReportNumber END) AS ContractorUTReportNumber,
                           Max(CASE NdtType WHEN 'UT' THEN ResponseReportDatetime END) AS UTDate,
                           Max(CASE NdtType WHEN 'UT' THEN Defect END) AS UTDefect,
                           Max(CASE NdtType WHEN 'UT' THEN Remark END) AS UTSegment
                     FROM  ReportTable  i)b
--ORDER BY b.Id DESC

【讨论】:

  • Msg 207, Level 16, State 1, Line 67 列名“Id”无效。
  • 或许可以考虑在此处使用 CTE,这也会使内容更易于阅读。
  • @EhsanAkbar 你想订购什么最终结果集? NdtReportDetails 表的Id ??
  • @TimBiegeleisen 更改为 CTE,而不是多个 INNER Query。
猜你喜欢
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多