Oracle查询获取批量行

时间:2018-05-14 16:28:53

标签: oracle

所以这是我的问题:我需要获取批量行(select语句)以便迁移到另一个数据库(除了oracle之外)。

建议的解决方案:我采用多批行(可能使用rowid?)示例:

batch1: 0-10000, 
batch2: 10000 - 20000,
batchn: 10000(n) - 10000(n+1)

那么我的查询应该是什么?

batch1: select * from table_name where rownum >= 0 and rownum < 10000,
batch2: select * from table_name where rownum >= 10000 and rownum < 20000,
batch n: select * from table_name where rownum >= 10000*n and rownum < 10000*(n+1) 

这不起作用(只有第一个选择才有效)。

PS,我从nodejs应用程序中提取这些数据,因此我在for循环中发送这些批处理查询。

3 个答案:

答案 0 :(得分:1)

使用rownum并不是一个好主意,因为不能保证在不同的查询中为相同的行分配相同的rownum值。

如果表具有唯一标识行的列的任意组合,则最好根据该列生成排名并使用该排名来标识批次行。例如:

SELECT * FROM (
  SELECT table.*, RANK() OVER (ORDER BY column1, column2) as my_rank
  FROM table
  )
WHERE my_rank >= 10000 AND my_rank < 20000

这适用于任何范围,并且只要所用列中的值不更改并唯一标识行,就可以重现。 (实际上,我认为即使它们不能唯一地标识一行,它也是可用的,只要它们能够将行分成足够小的批次。)

缺点是MY_RANK将包含在输出中。您可以通过明确列出您想要选择的列来避免这种情况;或者,当您将数据加载到其他数据库时,可能更容易将其过滤掉。

答案 1 :(得分:1)

说明我的评论:

-- Between rows --
SELECT * FROM 
   ( SELECT deptno, ename, sal, ROW_NUMBER() OVER (ORDER BY ename) Row_Num 
       FROM scott.emp
   )
WHERE Row_Num BETWEEN 5 and 10
/

如果需要,您可以在&lt; =和&gt; =之间替换运算符。 这是我在输出中看到的内容:

DEPTNO  ENAME   SAL    ROW_NUM
   20   FORD    3000    5
   30   JAMES   950     6
   20   JONES   2975    7
   10   KING    5000    8
   30   MARTIN  1250    9
   10   MILLER  1300    10

答案 2 :(得分:0)

如果要保留rowid,请使用以下SQL。这个SQL需要4分20秒才能在2 CPU服务器上运行2.18亿行表,其中18 GB用于数据库。

CREATE TABLE rowids
AS
    WITH
        aset
        AS
            (SELECT ROWID AS row_id, row_number () OVER (ORDER BY ROWID) r
               FROM amiadm.big_table)
    SELECT *
      FROM aset
     WHERE MOD (r, 10000) = 0;

创建此表后,使用以下内容循环显示:

BEGIN
    FOR recs
        IN (  SELECT row_id
                   , LAG (row_id) OVER (ORDER BY row_id) prev_row_id
                   , LEAD (row_id) OVER (ORDER BY row_id) next_row_id
                FROM rowids
            ORDER BY row_id)
    LOOP
        IF prev_row_id IS NULL
        THEN
            SELECT *
              FROM big_table
             WHERE ROWID <= recs.row_id;
        ELSIF next_row_id IS NULL
        THEN
            SELECT *
              FROM big_table
             WHERE ROWID > row_id;
        ELSE
            SELECT *
              FROM big_table
             WHERE ROWID > prev_row_id
               AND ROWID <= row_id;
        END IF;
    END LOOP;
END;