在Oracle Sql中组合多个查询的结果

时间:2015-05-20 11:04:34

标签: sql oracle

数据库 - Oracle数据库10g 10.2.0.4.0版, 使用Oracle SQL Developer

修改 对不起:Query-1应该是:

SELECT TABLE_NAME FROM USER_TABLES;

之前它是SELECT OWNER, TABLE_NAME FROM ALL_TABLES;

输出-1:我拥有的所有表格

查询-2: SELECT COUNT(*) FROM MYTABLE_1;

输出-2:特定表 MYTABLE_1

中的总行数

查询-3: SELECT MAX(ORA_ROWSCN) FROM MYTABLE_1;

Query-3的输出是一个数字(493672033308),它在Query-4中进一步使用

查询-4: SELECT SCN_TO_TIMESTAMP(493672033308) FROM DUAL;

输出-4是特定表 MYTABLE_1

的上次更新时间

如何将所有这些结合起来以获取所有用户表的列表,其中包含列标题为 TABLE_NAME,TOTAL_ROWS,LAST_UPDATE_TIME

的总共3列

EDIT-2:最终查询:

SELECT t.TABLE_NAME , m.TIMESTAMP , t.NUM_ROWS , ((NVL(t.NUM_ROWS,0) + m.INSERTS) - m.DELETES) AS TOT_ROWS FROM USER_TABLES t LEFT OUTER JOIN USER_TAB_MODIFICATIONS m ON t.TABLE_NAME = m.TABLE_NAME ORDER BY t.TABLE_NAME;

感谢APC,StevieG,bob dylan:)

4 个答案:

答案 0 :(得分:1)

我会这样做:

SELECT a.OWNER, a.TABLE_NAME, a.NUM_ROWS, b.TIMESTAMP
FROM ALL_TABLES a
INNER JOIN DBA_TAB_MODIFICATIONS b ON a.OWNER = b.TABLE_OWNER AND a.TABLE_NAME = b.TABLE_NAME

编辑 - 这是正确的,但NUM_ROWS可能不完全准确: http://www.dba-oracle.com/t_count_rows_all_tables_in_schema.htm

答案 1 :(得分:1)

我没有足够的代表发表评论,但StevieG的答案仍然返回错误的原因是因为您无法访问dba_tab_modifications视图,而是使用user_ / all_ equivalent与您的权限一致:

SELECT a.OWNER, a.TABLE_NAME, a.NUM_ROWS, b.TIMESTAMP
FROM ALL_TABLES a
INNER JOIN ALL_TAB_MODIFICATIONS b ON a.OWNER = b.TABLE_OWNER AND a.TABLE_NAME = b.TABLE_NAME

答案 2 :(得分:1)

您希望使用数据字典的内容来驱动查询。这只能在过程中使用动态SQL来完成。

要记住一些要点:

  1. Oracle维护SCN时间戳映射以支持闪回查询。它只保留支持的UNDO_RETENTION期间的映射。因此,我们只能对具有最近活动的表使用SCN_TO_TIMESTAMP()。 Staler表将投掷ORA-08181。
  2. 没有行的表将没有关联的SCN。如果我们为SCN传递null,则SCN_TO_TIMESTAMP()会抛出。
  3. 因此,强大的解决方案非常复杂。这个使用DBMS_OUTPUT来显示结果;其他机制可用:

    declare
        n pls_integer;
        max_scn number;
        x_scn_too_old exception;
        pragma exception_init(x_scn_too_old ,-08181);
        txt varchar2(30);
    begin
        for lrec in ( select table_name from user_tables )
        loop
            execute immediate 
                'select count(*), max(ora_rowscn) from '
                    || lrec.table_name
                    into n, max_scn;
            dbms_output.put(lrec.table_name
                                    ||' count='||to_char(n));
            begin
                if n > 0 then
                    select to_char(scn_to_timestamp(max_scn), 'yyyy-mm-dd hh24:mi:ss.ff3')
                    into txt
                    from dual;
                else
                    txt := null;
                end if;
            exception
                when x_scn_too_old then
                    txt := ('earlier');
            end;
            dbms_output.put_line(' ts='||txt );
        end loop;
    end;
    /
    

    使用USER_TABLES中的NUM_ROWS和USER_TAB_MODIFICATIONS视图,有一个纯SQL替代方法。 Oracle维护此视图以监视表的统计信息的过时性。当您使用10g时,这将自动发生(在9i中我们必须打开特定表的监控)。

    USER_TAB_MODIFICATIONS为每个表上的DML活动提供了数字,这很简洁,因为我们可以将这些数字添加到NUM_ROWS以获得准确的总数,这比发布COUNT()更有效。

    再说几点。

    1. 任何缺少统计信息的表都会有NUM_ROWS = 0。因此,我在算术列
    2. 中使用NVL()
    3. USER_TAB_MODIFICATIONS仅包含自上次收集统计信息以来已更改的表的数据。一旦我们收集了关于表的统计信息,它就会从该视图中消失,直到发出更多DML。所以,使用外连接。
    4. 请注意,我们只会为具有陈旧统计信息的表提供时间戳。这比上面使用的SCN_TO_TIMESTAMP更难以预测,因为它取决于您的统计数据收集策略。
    5. 所以这是:

      select t.table_name
              , m.timestamp
              , t.num_rows
              , ((nvl(t.num_rows,0) + m.inserts) - m.deletes) as tot_rows
      from user_tables t
           left outer join USER_TAB_MODIFICATIONS m
               on t.table_name = m.table_name
      order by t.table_name
      /
      

      也许最好的解决方案是组合,使用NUM_ROWS和USER_TAB_MODIFICATIONS来避免计数,并且只检查具有新统计信息的表的ORA_ROWSCN。

      请注意,这只是一个问题,因为您没有自己的日记记录或表审核。许多地方在其表格中添加元数据列以跟踪更改数据(例如CREATED_ON,CREATED_BY,UPDATED_ON,UPDATED_BY)。

答案 3 :(得分:-1)

解决您的问题很简单。 使用子查询因子。这对你有帮助。

在下面的链接中找到参考。

http://oracle-base.com/articles/misc/with-clause.php