这个 Oracle SQL SELECT 不应该工作。为什么呢?
This Oracle SQL SELECT shouldn't work. Why does it?
我正在调试 Oracle 19c 中的查询,该查询试图按不在查询中的字段对 SELECT DISTINCT
结果进行排序。 (注意:这是错误的做法,不要这样做。)
此查询试图 return 一个唯一的客户名称列表,其中最近的销售日期排在最前面。它 return 是一个预期的错误,“ORA-01791:不是 SELECTed 表达式”。
SELECT DISTINCT CUSTOMER_NAME
FROM SALES
ORDER BY LAST_SALE_DATE DESCENDING;
它 return 是一个错误,因为查询试图按尚未 select 编辑的字段对结果进行排序。到目前为止这是有道理的。
但是,如果我只是将 FETCH FIRST 6 ROWS ONLY
添加到查询中,它会 而不是 return 错误(尽管结果不正确,所以不要做这个)。但问题是为什么Oracle没有return错误信息?
SELECT DISTINCT CUSTOMER_NAME
FROM SALES
ORDER BY LAST_SALE_DATE DESCENDING
FETCH FIRST 6 ROWS ONLY;
为什么添加 FETCH FIRST 6 ROWS ONLY
可以实现此功能?
补充:如果有多个记录具有相同的名称和日期,则不正确的查询将 return 重复。搜索类似“sql select distinct order by another column”之类的内容将显示几种正确的方法。
查询的解释计划显示了正在发生的事情。
解析器重写 fetch...
子句 - 它将解析 row_number
添加到 select
列表,并使用带有行号过滤器的外部查询。它将 unique
指令(select
中的 distinct
指令)推入子查询,这不是有效的转换;在 Oracle 的 fetch...
.
实现中,我认为这是一个明显的 bug
解释计划显示了解析器在其中应用 unique
并添加分析 row_number()
创建内联视图的步骤。它不显示投影(视图中包含哪些列),并且 - 关键 - 它适用于 unique
的内容。一点点实验给出了答案:它将 unique
应用于 customer_name
和 last_sales_date
.
的 组合
这可能已被报告并可能在最近的版本中得到修复 - 您的 Oracle 版本是多少?
我正在调试 Oracle 19c 中的查询,该查询试图按不在查询中的字段对 SELECT DISTINCT
结果进行排序。 (注意:这是错误的做法,不要这样做。)
此查询试图 return 一个唯一的客户名称列表,其中最近的销售日期排在最前面。它 return 是一个预期的错误,“ORA-01791:不是 SELECTed 表达式”。
SELECT DISTINCT CUSTOMER_NAME
FROM SALES
ORDER BY LAST_SALE_DATE DESCENDING;
它 return 是一个错误,因为查询试图按尚未 select 编辑的字段对结果进行排序。到目前为止这是有道理的。
但是,如果我只是将 FETCH FIRST 6 ROWS ONLY
添加到查询中,它会 而不是 return 错误(尽管结果不正确,所以不要做这个)。但问题是为什么Oracle没有return错误信息?
SELECT DISTINCT CUSTOMER_NAME
FROM SALES
ORDER BY LAST_SALE_DATE DESCENDING
FETCH FIRST 6 ROWS ONLY;
为什么添加 FETCH FIRST 6 ROWS ONLY
可以实现此功能?
补充:如果有多个记录具有相同的名称和日期,则不正确的查询将 return 重复。搜索类似“sql select distinct order by another column”之类的内容将显示几种正确的方法。
查询的解释计划显示了正在发生的事情。
解析器重写 fetch...
子句 - 它将解析 row_number
添加到 select
列表,并使用带有行号过滤器的外部查询。它将 unique
指令(select
中的 distinct
指令)推入子查询,这不是有效的转换;在 Oracle 的 fetch...
.
解释计划显示了解析器在其中应用 unique
并添加分析 row_number()
创建内联视图的步骤。它不显示投影(视图中包含哪些列),并且 - 关键 - 它适用于 unique
的内容。一点点实验给出了答案:它将 unique
应用于 customer_name
和 last_sales_date
.
这可能已被报告并可能在最近的版本中得到修复 - 您的 Oracle 版本是多少?