Sql 在Oracle中,如何从排序结果中获取包含不同值的页面?
我在一对多关系中有两列。我想对多个进行排序,并返回第一个出现的一个。我需要翻页查看数据,例如,我需要能够获得第三组10个唯一值 我有这样一个问题:Sql 在Oracle中,如何从排序结果中获取包含不同值的页面?,sql,oracle,Sql,Oracle,我在一对多关系中有两列。我想对多个进行排序,并返回第一个出现的一个。我需要翻页查看数据,例如,我需要能够获得第三组10个唯一值 我有这样一个问题: SELECT id, name FROM table1 INNER JOIN table2 ON table2.fkid = table1.id ORDER BY name, id; id | name ---------------- 2 | apple 23 | banana 77 | cranberry
SELECT id, name
FROM table1
INNER JOIN table2 ON table2.fkid = table1.id
ORDER BY name, id;
id | name
----------------
2 | apple
23 | banana
77 | cranberry
23 | dark chocolate
8 | egg
2 | yak
19 | zebra
SELECT * FROM (
SELECT * FROM (
SELECT id FROM (
SELECT id, name, row_number() over (partition by id order by name) rn
FROM table1
INNER JOIN table2 ON table2.fkid = table1.id
)
) WHERE rn=1 ORDER BY name, id
) WHERE rownum>=1 and rownum<=4;
对于表1中的每一行,表2中可以有多行
我的查询结果如下所示:
SELECT id, name
FROM table1
INNER JOIN table2 ON table2.fkid = table1.id
ORDER BY name, id;
id | name
----------------
2 | apple
23 | banana
77 | cranberry
23 | dark chocolate
8 | egg
2 | yak
19 | zebra
SELECT * FROM (
SELECT * FROM (
SELECT id FROM (
SELECT id, name, row_number() over (partition by id order by name) rn
FROM table1
INNER JOIN table2 ON table2.fkid = table1.id
)
) WHERE rn=1 ORDER BY name, id
) WHERE rownum>=1 and rownum<=4;
我需要一页一页地浏览结果集,每个页面包含n个唯一的ID。例如,如果start=1,n=4,我想返回
2
23
77
8
按照它们的排序顺序,即名称,其中id返回到其第一次出现的位置。同样,如果start=3,n=4,order=desc,我希望
8
23
77
2
我试过这个:
SELECT * FROM (
SELECT id, ROWNUM rnum FROM (
SELECT DISTINCT id FROM (
SELECT id, name
FROM table1
INNER JOIN table2 ON table2.fkid = table1.id
ORDER BY name, id)
WHERE ROWNUM <= 4)
WHERE rnum >=1)
…但我仍然得到重复的ID。您可能需要对其进行一点调试,但它将是这样的:
SELECT id, name
FROM table1
INNER JOIN table2 ON table2.fkid = table1.id
ORDER BY name, id;
id | name
----------------
2 | apple
23 | banana
77 | cranberry
23 | dark chocolate
8 | egg
2 | yak
19 | zebra
SELECT * FROM (
SELECT * FROM (
SELECT id FROM (
SELECT id, name, row_number() over (partition by id order by name) rn
FROM table1
INNER JOIN table2 ON table2.fkid = table1.id
)
) WHERE rn=1 ORDER BY name, id
) WHERE rownum>=1 and rownum<=4;
它有点复杂,我倾向于怀疑它可以简化,但它应该可以工作。你可以在WHERE子句中放置任何你想要的开始和结束位置——我在这里展示的start=2和n=4是从一个单独的表中提取出来的,但是你可以通过使用几个参数来简化事情
SQL> ed
Wrote file afiedt.buf
1 with t as (
2 select 2 id, 'apple' name from dual union all
3 select 23, 'banana' from dual union all
4 select 77, 'cranberry' from dual union all
5 select 23, 'dark chocolate' from dual union all
6 select 8, 'egg' from dual union all
7 select 2, 'yak' from dual union all
8 select 19, 'zebra' from dual
9 ),
10 x as (
11 select 2 start_pos, 4 n from dual
12 )
13 select *
14 from (
15 select distinct
16 id,
17 dense_rank() over (order by min_id_rnk) outer_rnk
18 from (
19 select id,
20 min(rnk) over (partition by id) min_id_rnk
21 from (
22 select id,
23 name,
24 rank() over (order by name) rnk
25 from t
26 )
27 )
28 )
29 where outer_rnk between (select start_pos from x) and (select start_pos+n-1 from x)
30* order by outer_rnk
SQL> /
ID OUTER_RNK
---------- ----------
23 2
77 3
8 4
19 5
如果需要对结果进行分页,则应用程序的搜索功能可能已损坏。阅读杰夫·阿特伍德(Jeff Atwood)最近在该教区的博客:感谢链接;这是一本有趣的书。但是,我没有显示搜索结果。显示的数据数量有限,数量取决于用户的角色。有时候,它不仅仅是一个页面上的滚动,或者是一个JavaScript组件中的滚动,尽管我的计划是在有时间重新设计UI时转向连续滚动。工作非常完美,速度也很快。非常感谢!