我有一个查询,用于搜索我们网络中的子部门列表。当查询在没有任何过滤器的情况下执行时,它会在每次执行时返回不同数量的行
SELECT DISTINCT
t1.ZRESUBDIV,
t1.SUBDIV_NAME
FROM M_STAGE_WP_PFUNCT_LOC t1
WHERE ROWNUM <= 200 -- normally a filter goes here
ORDER BY t1.SUBDIV_NAME
Run Code Online (Sandbox Code Playgroud)
执行 1
ZRESUBDIV SUBDIV_NAME ------------ -------------------------------------- --------------- 262 亚历山大 400 艾伦沃特 第671章 第372章 277 比奇堡 200桥 第374章 543 中央比尤特 第208章 第324章 340芝加哥 ...
执行 2
ZRESUBDIV SUBDIV_NAME ------------ -------------------------------------- --------------- 670 阿尔布雷达 262 亚历山大 400 艾伦沃特 第671章 第372章 277 比奇堡 604 黑脚 200桥 第607章 第354章 543 中央比尤特 ...
还有缺失的数据:细分巴吞鲁日虽然在数据中但从未出现过。
如果我删除 ROWNUM,所有数据都会正确返回。我需要保留 ROWNUM,因为查询支持 WHERE 子句,并在细分名称上使用过滤器。
这是什么原因?
Bal*_*app 10
ROWNUM
之前评估过ORDER BY
,这不是ROWNUM
应该如何使用。要ROWNUM
正确使用,请使用如下查询:
SELECT * FROM
(
SELECT DISTINCT
t1.ZRESUBDIV,
t1.SUBDIV_NAME
FROM M_STAGE_WP_PFUNCT_LOC t1
ORDER BY t1.SUBDIV_NAME
)
WHERE ROWNUM <= 200;
Run Code Online (Sandbox Code Playgroud)
但这是旧的。由于您使用的是 12c,请使用以下命令:
SELECT DISTINCT
t1.ZRESUBDIV,
t1.SUBDIV_NAME
FROM M_STAGE_WP_PFUNCT_LOC t1
ORDER BY t1.SUBDIV_NAME
FETCH FIRST 200 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
ROWNUM
是做这种查询的错误方式。正如@Kris Johnston 在带有“cart and the horse”比喻的评论中所解释的那样:该WHERE
子句在 之前执行ORDER BY
,如果没有 ,您将无法保证结果的顺序ORDER BY
,所以是的,每次运行都会产生不同的结果。
您可以改用ROW_NUMBER()
和子查询:
SELECT
t.ZRESUBDIV,
t.SUBDIV_NAME
FROM
( SELECT
t1.ZRESUBDIV,
t1.SUBDIV_NAME,
ROW_NUMBER() OVER (ORDER BY t1.SUBDIV_NAME) AS RN
FROM M_STAGE_WP_PFUNCT_LOC t1
WHERE --- your filter goes here but NOT any ROWNUM
GROUP BY
t1.ZRESUBDIV,
t1.SUBDIV_NAME
) t
WHERE
t.RN <= 200
ORDER BY
t.SUBDIV_NAME ;
Run Code Online (Sandbox Code Playgroud)
internalORDER BY
定义将选择哪些行(因为前 200 行将具有从 1 到 200 的 row_numbers),而 externalORDER BY
是可选的,仅对演示顺序有影响。
请注意,排序不是全部,即您可能有相同的行SUBDIV_NAME
。如果您希望完全指定订单,您可以将它们更改ORDER BY
为ORDER BY SUBDIV_NAME, BYZRESUBDIV
(例如)。
@Balazs Papp 的回答中的其他 2 个查询也很好,如果不是更好的话。ROW_NUMBER()
在实施之前,第一个可能被广泛使用,因为它适用于旧版本。第二个肯定是你能得到的最简洁的,只要你是 12c 版本。
归档时间: |
|
查看次数: |
3249 次 |
最近记录: |