oracle左连接查询进行分页

时间:2015-04-02 08:52:42

标签: sql oracle paging

select rownum rnum, * from group g 
  left join user u on u.group_id = g.id 
  where rnum between 1, 2
  order by g.created_at desc;

假设最新的group1,group2各有2个用户。

然后上面的查询将返回group1的2条记录。

我想根据组记录设置rownum,这样我就可以拥有group1和group2(即:上面的查询应该返回4条记录)。

我尝试了dense_rank(),但我必须按group_id而不是created_at来订购记录。

有人可以给我这个查询吗?

3 个答案:

答案 0 :(得分:0)

select rownum rnum, * from group g 
  left join user u on u.group_id = g.id 
  where rnum between 1, 2
  order by g.created_at desc;

您的查询语法上和逻辑上不正确

如果您正在寻找 PAGINATION 查询,则需要先了解 ROWNUM 的工作原理。

例如,

我有以下员工表。

SQL> SELECT empno, sal FROM emp ORDER BY sal DESC;

     EMPNO        SAL
---------- ----------
      7839       5000
      7902       3000
      7788       3000
      7566       2975
      7698       2850
      7782       2450
      7499       1600
      7844       1500
      7934       1300
      7521       1250
      7654       1250
      7876       1100
      7900        950
      7369        800

14 rows selected.

SQL>

我需要第5,第6,第7和第8名受薪最高的员工

SQL> SELECT empno, sal
  2  FROM   (SELECT empno, sal, ROWNUM AS rnum
  3          FROM   (SELECT empno, sal
  4                  FROM   emp
  5                  ORDER BY sal DESC
  6                 )
  7          WHERE rownum <= 8)
  8  WHERE  rnum >= 5;

     EMPNO        SAL
---------- ----------
      7698       2850
      7782       2450
      7499       1600
      7844       1500

SQL>

您可以使用其他分页方式。如果您使用 12c ,则可以使用新的前N行限制功能。请查看链接http://oracle-base.com/articles/12c/row-limiting-clause-for-top-n-queries-12cr1.php#paging以获取更多详细信息。

答案 1 :(得分:0)

  

我尝试了dense_rank(),但我必须按group_id排序记录   created_at。

这是个好主意:

select id, name, created_at, usid
  from (
    select dense_rank() over (order by created_at desc) rnk, 
        g.id, g.name, g.created_at, u.id usid
      from groups g left join users u on u.group_id = g.id)
  where rnk < 3 order by id

SQLFiddle

结果(我添加了一个显示的组,只选择了最新的组合):

        ID NAME       CREATED_AT  USID
---------- ---------- ----------- ----------
         2 Group2     2015-01-09  Kyle
         2 Group2     2015-01-09  Eric
         3 Group3     2015-01-12  Kenny
         3 Group3     2015-01-12  Butters

或者您也可以使用:

select g.id, name, created_at, u.id usid
  from (
    select * from (
        select * from groups order by created_at desc) 
      where rownum < 3 ) g
  left join users u on g.id = u.group_id
  order by g.id

答案 2 :(得分:0)

我认为您正在使用row_number()子句寻找partition by

select id, name, created_at, usid
from (select row_number() over (partition by g.id order by created_at desc) as seqnum, 
             g.id, g.name, created_at, u.id as usid
      from groups g left join
           users u
           on u.group_id = g.id
     ) ug
where seqnum <= 2
order by id;