SELECT DISTINCT我正在 Oracle 19c 中调试一个查询,该查询试图按不在查询中的字段对结果进行排序。(注意:这是错误的做法,请勿这样做。)
此查询尝试返回一个唯一的客户名称列表,首先按最近的销售日期排序。它返回预期错误“ORA-01791:不是 SELECTed 表达式”。
SELECT DISTINCT CUSTOMER_NAME
FROM SALES
ORDER BY LAST_SALE_DATE DESCENDING;
Run Code Online (Sandbox Code Playgroud)
它返回错误,因为查询尝试按尚未选择的字段对结果进行排序。到目前为止这是有道理的。
但是,如果我只是添加FETCH FIRST 6 ROWS ONLY到查询中,它不会返回错误(尽管结果不正确,所以不要这样做)。但问题是为什么Oracle不返回错误信息呢?
SELECT DISTINCT CUSTOMER_NAME
FROM SALES
ORDER BY LAST_SALE_DATE DESCENDING
FETCH FIRST 6 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
为什么添加会FETCH FIRST 6 ROWS ONLY起作用?
补充:如果有多个具有相同名称和日期的记录,则错误的查询将返回重复项。搜索诸如“sql select unique order by another column”之类的内容将显示几种正确的方法来执行此操作。
小智 8
查询的解释计划显示了正在发生的情况。
解析器重写该fetch...子句 - 它将分析添加row_number到select列表中,并使用带有行号过滤器的外部查询。它将unique指令(distinct来自您的指令select)推送到子查询中,这不是有效的转换;我认为这是Oracle 实现中的一个明显错误fetch...。
解释计划显示了解析器在应用时创建内联视图unique并添加分析的步骤row_number()。它不显示投影(视图中包含哪些列),以及 - 重要的是 - 它适用于什么unique。不过,一点点实验就给出了答案:它适用unique于和的组合。customer_namelast_sales_date
有可能这个问题已经被报告过,并且可能在最近的版本中得到了修复 - 您的 Oracle 版本是什么?