【问题标题】:I am getting error using ORDERBY in Sub Query (The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries)在子查询中使用 ORDERBY 时出现错误(ORDER BY 子句在视图、内联函数、派生表、子查询中无效)
【发布时间】:2014-08-20 17:45:21
【问题描述】:

ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP 或 FOR XML。

我正在使用 join 从三个表中获取结果。现在在结果中我得到了 RMA_ID 的多条记录,但我只想要基于 TBL_RMA_SHIPPING.SHIP_ADMIN_STATUS 的最新记录。

我在查询中收到此错误。请帮帮我。

SELECT RMA_ENQUIRY.RMA_ID,
       PART_NUMBER_TBL.PART_NO, 
       PART_SERIAL.SERIAL_NUM,
       RMA_ENQUIRY.RMA_TYPE,
       RMA_ENQUIRY.RMA_FAILURE_TYPE,
       RMA_ENQUIRY.RMA_COMPLAINT,
       RMA_ENQUIRY.RMA_ADDITIONAL_INFORMATION,
       RMA_ENQUIRY.RMA_REC_DATE,
       RMA_ENQUIRY.RMA_STATUS,
       RMA_ENQUIRY.RMA_SHIP_STATUS,
       (select TBL_RMA_SHIPPING.SHIP_ADMIN_STATUS from TBL_RMA_SHIPPING where TBL_RMA_SHIPPING.SHIP_RMAID=RMA_ENQUIRY.RMA_ID order by TBL_RMA_SHIPPING.UPDATE_STATUS_DATE),
       RMA_ENQUIRY.[USER_ID],
       TBL_RMA_SHIPPING.SHIP_DETAILS
  FROM RMA_ENQUIRY 
       LEFT JOIN PART_NUMBER_TBL 
                  ON RMA_ENQUIRY.RMA_PART_NO=PART_NUMBER_TBL.PARTID 
       LEFT JOIN PART_SERIAL 
                  ON RMA_ENQUIRY.RMA_SERIAL_NO=PART_SERIAL.SERIAL_ID
       LEFT JOIN TBL_RMA_SHIPPING ON RMA_ENQUIRY.RMA_ID=TBL_RMA_SHIPPING.SHIP_RMAID
                  WHERE RMA_ENQUIRY.RMA_STATUS='A' AND RMA_ENQUIRY.RMA_SHIP_STATUS=1
                  ORDER BY RMA_ENQUIRY.RMA_REC_DATE DESC

【问题讨论】:

  • 你有这么好的连接设置......然后把这个位扔到选择语句中:“(从 TBL_RMA_SHIPPING 中选择 TBL_RMA_SHIPPING.SHIP_ADMIN_STATUS 其中 TBL_RMA_SHIPPING.SHIP_RMAID=RMA_ENQUIRY.RMA_ID 按 TBL_RMA_SHIPPING.UPDATE_STATUS_DATE 排序), " 将其更改为 join 并正确调用该字段......它会消除这个错误和一堆混乱,可能也会让这一切变得更快。在 select 语句中按子查询排序没有逻辑意义
  • 我猜这是 SQL server 而不是 mySQL 作为 top 和 For XML 被引用。如果要加入表是左联接不返回行并且必须有值,为什么需要在选择中进行子查询?如果是这样,您确定您的加入在正确的列上吗? fi 所以您需要更改查询,以便它根据该行的相关数据返回一个和唯一一个记录/列。

标签: sql sql-server join sql-order-by


【解决方案1】:
SELECT RMA_ENQUIRY.RMA_ID,
       PART_NUMBER_TBL.PART_NO, 
       PART_SERIAL.SERIAL_NUM,
       RMA_ENQUIRY.RMA_TYPE,
       RMA_ENQUIRY.RMA_FAILURE_TYPE,
       RMA_ENQUIRY.RMA_COMPLAINT,
       RMA_ENQUIRY.RMA_ADDITIONAL_INFORMATION,
       RMA_ENQUIRY.RMA_REC_DATE,
       RMA_ENQUIRY.RMA_STATUS,
       RMA_ENQUIRY.RMA_SHIP_STATUS,
       TBL_RMA_SHIPPING.SHIP_ADMIN_STATUS, --This doesn't work why?  you only want the max? then...
       --(select TBL_RMA_SHIPPING.SHIP_ADMIN_STATUS from TBL_RMA_SHIPPING where TBL_RMA_SHIPPING.SHIP_RMAID=RMA_ENQUIRY.RMA_ID order by TBL_RMA_SHIPPING.UPDATE_STATUS_DATE),
       RMA_ENQUIRY.[USER_ID],
       TBL_RMA_SHIPPING.SHIP_DETAILS
  FROM RMA_ENQUIRY 
       LEFT JOIN PART_NUMBER_TBL 
                  ON RMA_ENQUIRY.RMA_PART_NO=PART_NUMBER_TBL.PARTID 
       LEFT JOIN PART_SERIAL 
                  ON RMA_ENQUIRY.RMA_SERIAL_NO=PART_SERIAL.SERIAL_ID
       LEFT JOIN TBL_RMA_SHIPPING ON RMA_ENQUIRY.RMA_ID=TBL_RMA_SHIPPING.SHIP_RMAID
                  WHERE RMA_ENQUIRY.RMA_STATUS='A' AND RMA_ENQUIRY.RMA_SHIP_STATUS=1
                  ORDER BY RMA_ENQUIRY.RMA_REC_DATE DESC

如果你只想要最大...

SELECT RMA_ENQUIRY.RMA_ID,
       PART_NUMBER_TBL.PART_NO, 
       PART_SERIAL.SERIAL_NUM,
       RMA_ENQUIRY.RMA_TYPE,
       RMA_ENQUIRY.RMA_FAILURE_TYPE,
       RMA_ENQUIRY.RMA_COMPLAINT,
       RMA_ENQUIRY.RMA_ADDITIONAL_INFORMATION,
       RMA_ENQUIRY.RMA_REC_DATE,
       RMA_ENQUIRY.RMA_STATUS,
       RMA_ENQUIRY.RMA_SHIP_STATUS,
       max(TBL_RMA_SHIPPING.SHIP_ADMIN_STATUS), 
       RMA_ENQUIRY.[USER_ID],
       TBL_RMA_SHIPPING.SHIP_DETAILS
  FROM RMA_ENQUIRY 
       LEFT JOIN PART_NUMBER_TBL 
                  ON RMA_ENQUIRY.RMA_PART_NO=PART_NUMBER_TBL.PARTID 
       LEFT JOIN PART_SERIAL 
                  ON RMA_ENQUIRY.RMA_SERIAL_NO=PART_SERIAL.SERIAL_ID
       LEFT JOIN TBL_RMA_SHIPPING ON RMA_ENQUIRY.RMA_ID=TBL_RMA_SHIPPING.SHIP_RMAID
                  WHERE RMA_ENQUIRY.RMA_STATUS='A' AND RMA_ENQUIRY.RMA_SHIP_STATUS=1

GROUP BY RMA_ENQUIRY.RMA_ID,
       PART_NUMBER_TBL.PART_NO, 
       PART_SERIAL.SERIAL_NUM,
       RMA_ENQUIRY.RMA_TYPE,
       RMA_ENQUIRY.RMA_FAILURE_TYPE,
       RMA_ENQUIRY.RMA_COMPLAINT,
       RMA_ENQUIRY.RMA_ADDITIONAL_INFORMATION,
       RMA_ENQUIRY.RMA_REC_DATE,
       RMA_ENQUIRY.RMA_STATUS,
       RMA_ENQUIRY.RMA_SHIP_STATUS,
       RMA_ENQUIRY.[USER_ID],
       TBL_RMA_SHIPPING.SHIP_DETAILS
       ORDER BY RMA_ENQUIRY.RMA_REC_DATE DESC

【讨论】:

  • 实际上,RMA_ENQUIRY 表包含了所有可以用 RMA_ID 标识的查询信息,而 TBL_RMA_SHIPPING 表包含了 RMA_ENQUIRY 表中发货状态为“1”的查询的发货详细信息。我正在多次更新单个 RMA_ID 的查询状态(待处理、已发送、处理中等),并在我的查询中获取相同的状态。现在的问题是我得到了 RMA_ID 的多条记录(运输状态),但我只想要结果中的最新状态而不是每个结果。
【解决方案2】:

在 SELECT 子句中使用子查询时,您只能返回 1 个值。使用 Top 1 将确保返回单个值。如果没有它,查询优化器会假定将返回多个值,这就是您首先要订购数据的原因。

如果在 FROM 子句中使用子查询,则顺序无关紧要,因为它将根据 ON 条件连接。在这种情况下,TOP 可用于根据您的业务需求限制结果集。但是,有一些变通方法可以使用 TOP 子句获取有序数据以提高 JOIN 性能。在 FROM 子句中使用子查询时,允许多条记录。

【讨论】:

  • 实际上,RMA_ENQUIRY 表包含了所有可以用 RMA_ID 标识的查询信息,而 TBL_RMA_SHIPPING 表包含了 RMA_ENQUIRY 表中发货状态为“1”的查询的发货详细信息。我正在多次更新单个 RMA_ID 的查询状态(待处理、已发送、处理中等),并在我的查询中获取相同的状态。现在的问题是我得到了 RMA_ID 的多条记录(运输状态),但我只想要结果中的最新状态而不是每个结果。
【解决方案3】:

您收到原始帖子中描述的错误的原因是因为就像它说的那样,在您的主选择的子选择中,您不能在那里有 ORDER BY。 xQbert 的解决方案只会为您提供具有该最大值的记录。例如,如果您有一个这样的表 movie_view_history:

|movie_id|view_date|
--------------------
|  1     |1/1/2014 |
|  1     |1/2/2014 |
|  2     |2/1/2014 |
|  2     |2/2/2014 |

xQbert 的解决方案将返回:

select movie_id, MAX(view_date)
from movie_view_history
group by movie_id

|movie_id|view_date|
--------------------
|  1     |1/2/2014 |
|  2     |2/2/2014 |

但是,如果您想返回以下内容(谁知道,也许您有商业原因):

select 
    movie_id,
    (select max(view_date)
     from movie_view_history as [A]
     where [A].movie_id = [B].movie_id)
from movie_view_history as [B]

|movie_id|view_date|
--------------------
|  1     |1/2/2014 |
|  1     |1/2/2014 |
|  2     |2/2/2014 |
|  2     |2/2/2014 |

然后你可以使用以下内容:

SELECT 
  RMA_ENQUIRY.RMA_ID,
   PART_NUMBER_TBL.PART_NO, 
   PART_SERIAL.SERIAL_NUM,
   RMA_ENQUIRY.RMA_TYPE,
   RMA_ENQUIRY.RMA_FAILURE_TYPE,
   RMA_ENQUIRY.RMA_COMPLAINT,
   RMA_ENQUIRY.RMA_ADDITIONAL_INFORMATION,
   RMA_ENQUIRY.RMA_REC_DATE,
   RMA_ENQUIRY.RMA_STATUS,
   RMA_ENQUIRY.RMA_SHIP_STATUS,
   (select [B].SHIP_ADMIN_STATUS from TBL_RMA_SHIPPING AS [B] where [B].SHIP_RMAID=[A].SHIP_RMAID) AS [SHIP_ADMIN_STATUS],
   RMA_ENQUIRY.[USER_ID],
   [A].SHIP_DETAILS
FROM RMA_ENQUIRY 
   LEFT JOIN PART_NUMBER_TBL 
              ON RMA_ENQUIRY.RMA_PART_NO=PART_NUMBER_TBL.PARTID 
   LEFT JOIN PART_SERIAL 
              ON RMA_ENQUIRY.RMA_SERIAL_NO=PART_SERIAL.SERIAL_ID
   LEFT JOIN TBL_RMA_SHIPPING AS [A] ON RMA_ENQUIRY.RMA_ID=[A].SHIP_RMAID
WHERE RMA_ENQUIRY.RMA_STATUS='A' AND RMA_ENQUIRY.RMA_SHIP_STATUS=1
ORDER BY RMA_ENQUIRY.RMA_REC_DATE DESC

我喜欢 xQbert 的解决方案,但这完全取决于您要完成的任务!

【讨论】:

  • 无法绑定多部分标识符“TBL_RMA_SHIPPING.SHIP_DETAILS”。如果我正在运行查询,则会出现此错误。
  • 实际上,RMA_ENQUIRY 表包含了所有可以用 RMA_ID 标识的查询信息,而 TBL_RMA_SHIPPING 表包含了 RMA_ENQUIRY 表中发货状态为“1”的查询的发货详细信息。我正在多次更新单个 RMA_ID 的查询状态(待处理、已发送、处理中等),并在我的查询中获取相同的状态。现在的问题是我得到了 RMA_ID 的多条记录(运输状态),但我只想要结果中的最新状态而不是每个结果。
  • 我已更新以解决您的第一条评论。如果你只想要最新的记录,那么我会选择 xQbert 的解决方案(帖子中的第二个查询)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 2023-03-12
相关资源
最近更新 更多