Oracle_ROW_NUMBER 用于分页层级查询
Oracle_ ROW_NUMBER for paging hierarchy query
这次我遇到一个问题,就是层级的分页查询table。
table_name(id varchar2(50), id_parent varchar2(50) );
所以对于示例数据,我有:
WITH table_name AS
(
SELECT '3' id, '' id_parent FROM DUAL UNION ALL
SELECT '5' id, '3' id_parent FROM DUAL UNION ALL
SELECT 's' id, '3' id_parent FROM DUAL UNION ALL
SELECT '4' id, 'as' id_parent FROM DUAL UNION ALL
SELECT 'aa' id, 'as' id_parent FROM DUAL UNION ALL
SELECT 'as' id, '3' id_parent FROM DUAL UNION ALL
SELECT 'ad' id, '3' id_parent FROM DUAL UNION ALL
SELECT '2' id, '' id_parent FROM DUAL
)
SELECT LPAD('-', 2 * (level - 1), '-') || id AS id1,
id_parent,
rownum --Seem not legit here
FROM table_name
START WITH id_parent IS NULL
CONNECT BY PRIOR id = id_parent
--ORDER SIBLINGS BY id
;
这是预期的输出:
id id_parent rownum
2 1
3 2
--5 3 3
--ad 3 4
--as 3 5
----4 as 6
----aa as 7
--s 3 8
现在我指望 rownum 为 row_number 进行分页。作为 Oracle 层次结构查询的文档,这确保我可以将树显示为我们想要的预排序遍历,但通常 SQL,IMO 它不保证相同级别的节点将被排序(或不?)。
所以我需要 ROW_NUMBER() OVER (ORDER SIBLINGS BY id)
这样的东西。但是我没有找到类似的东西。
有什么方法可以解决这个问题吗?
先排序,然后使用子查询生成 ROWNUM
:
SELECT t.*,
ROWNUM
FROM (
SELECT LPAD('-', 2 * (level - 1), '-') || id AS id1,
id_parent
FROM table_name
START WITH id_parent IS NULL
CONNECT BY PRIOR id = id_parent
ORDER SIBLINGS BY id
) t;
您需要外部查询,因为查询中的执行顺序是:
- 行被选中;
- 然后应用
WHERE
子句过滤器(并且 ROWNUM
伪列是
为匹配所有 WHERE
子句过滤器的每一行生成 - 在这种情况下没有 WHERE
子句,因此所有行都将被编号);
- 然后应用
ORDER BY
子句。
在单个查询中应用此方法将获取在数据库中找到的行,然后为它们提供行号,最后对这些行进行排序(不是您想要的)。使用内部查询,您可以强制首先应用 ORDER BY
子句,然后在执行外部查询时生成行号。
这次我遇到一个问题,就是层级的分页查询table。
table_name(id varchar2(50), id_parent varchar2(50) );
所以对于示例数据,我有:
WITH table_name AS
(
SELECT '3' id, '' id_parent FROM DUAL UNION ALL
SELECT '5' id, '3' id_parent FROM DUAL UNION ALL
SELECT 's' id, '3' id_parent FROM DUAL UNION ALL
SELECT '4' id, 'as' id_parent FROM DUAL UNION ALL
SELECT 'aa' id, 'as' id_parent FROM DUAL UNION ALL
SELECT 'as' id, '3' id_parent FROM DUAL UNION ALL
SELECT 'ad' id, '3' id_parent FROM DUAL UNION ALL
SELECT '2' id, '' id_parent FROM DUAL
)
SELECT LPAD('-', 2 * (level - 1), '-') || id AS id1,
id_parent,
rownum --Seem not legit here
FROM table_name
START WITH id_parent IS NULL
CONNECT BY PRIOR id = id_parent
--ORDER SIBLINGS BY id
;
这是预期的输出:
id id_parent rownum
2 1
3 2
--5 3 3
--ad 3 4
--as 3 5
----4 as 6
----aa as 7
--s 3 8
现在我指望 rownum 为 row_number 进行分页。作为 Oracle 层次结构查询的文档,这确保我可以将树显示为我们想要的预排序遍历,但通常 SQL,IMO 它不保证相同级别的节点将被排序(或不?)。
所以我需要 ROW_NUMBER() OVER (ORDER SIBLINGS BY id)
这样的东西。但是我没有找到类似的东西。
有什么方法可以解决这个问题吗?
先排序,然后使用子查询生成 ROWNUM
:
SELECT t.*,
ROWNUM
FROM (
SELECT LPAD('-', 2 * (level - 1), '-') || id AS id1,
id_parent
FROM table_name
START WITH id_parent IS NULL
CONNECT BY PRIOR id = id_parent
ORDER SIBLINGS BY id
) t;
您需要外部查询,因为查询中的执行顺序是:
- 行被选中;
- 然后应用
WHERE
子句过滤器(并且ROWNUM
伪列是 为匹配所有WHERE
子句过滤器的每一行生成 - 在这种情况下没有WHERE
子句,因此所有行都将被编号); - 然后应用
ORDER BY
子句。
在单个查询中应用此方法将获取在数据库中找到的行,然后为它们提供行号,最后对这些行进行排序(不是您想要的)。使用内部查询,您可以强制首先应用 ORDER BY
子句,然后在执行外部查询时生成行号。