5

Oracle に一連のテーブルがあり、最大数の行を含むテーブルを特定したいと考えています。

したがって、A に 200 行、B に 345 行、C に 120 行ある場合、テーブル B を識別できるようにする必要があります。

これを達成するために実行できる簡単なクエリはありますか?

編集: 100 以上のテーブルがあるので、一般的なものを探しています。

4

7 に答える 7

12

あなたがOracleを使用していると言った場合、私はメタデータを照会するだけです.

select table_name, max(num_rows) from all_tables where table_name in ('A', 'B', 'C');

あなたの編集を見たところです。where句なしで上記を実行するだけで、データベース内の最大のテーブルが返されます。唯一の問題は、SYS$ テーブルなどを取得する可能性があることです。あるいは、自分の知識のためにこれを行っている場合は、

select table_name, num_rows from all_tables order by num_rows; 

最大のものを見ることができます。

于 2008-12-24T07:24:55.523 に答える
4

最大行数を持つスキーマ内のテーブル:

with data as 
(
 select table_name,
        to_number(extractvalue(xmltype(
                  dbms_xmlgen.getxml (
                 ' select count(*) c from ' || table_name)),
                  '/ROWSET/ROW/C')) countrows
 from   user_tables
)
select table_name, countrows
from   data 
where  countrows = (select max(countrows)
                    from   data);

dbms_xmlgen.getxml('select ....')は非常に柔軟性があります。

于 2008-12-24T08:34:13.043 に答える
3

単に ALL_TABLES.NUM_ROWS を取得するよりもはるかに遅くなる可能性が高い別の方法を次に示しますが、収集された統計に依存せず、正確な現在の値を提供します。現在の値は、実行にかかる時間によって異なります。

-- For running in SQLPlus you need this to see the output.
-- If running in Toad or similar tool, output is enabled by default

    SET SERVEROUTPUT ON SIZE 100000

    DECLARE
      l_rows  INTEGER;
      l_max_rows  INTEGER := 0;
      l_table_name  all_tables.table_name%TYPE := NULL;
    BEGIN
      FOR table_record IN (SELECT table_name FROM all_tables) LOOP

        EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '||table_record.table_name
          INTO l_rows;

        IF l_rows > l_max_rows THEN
          l_max_rows := l_rows;
          l_table_name := table_record.table_name;
        END IF;
      END LOOP;

      IF l_table_name IS NULL THEN
        dbms_output.put_line( 'All tables are empty' );
      ELSE
        dbms_output.put_line( 'Table ' || table_record.table_name || 
                              ' has ' || TO_CHAR(l_max_rows) || ' rows'
                            );
      END IF;
    END;
    /
于 2008-12-24T14:05:06.977 に答える
1

David Aldridge は、all_tables をクエリすると、テーブルの統計が欠落しているか、古いために誤った結果が返される可能性があることを正しく指摘しています。しかし、user_segments の使用にも問題があります。最高水準点の下にある削除されたブロックは、引き続きテーブルのサイズとしてカウントされます。

例:

SQL>create table t as select * from all_objects

Table created.

SQL>select blocks, bytes from user_segments where segment_name = 'T';

    BLOCKS      BYTES
---------- ----------
       768    6291456

SQL>delete from t

52676 rows deleted.

SQL>commit;

Commit complete.

SQL>select count(*) from t;

  COUNT(*)
----------
         0

SQL>select blocks, bytes from user_segments where segment_name = 'T';

    BLOCKS      BYTES
---------- ----------
       768    6291456

SQL>truncate table t;

Table truncated.

SQL>select blocks, bytes from user_segments where segment_name = 'T';

    BLOCKS      BYTES
---------- ----------
         8      65536
于 2008-12-29T23:51:06.713 に答える
1

次のように、データの 1 つのトロールで同じ結果を得ることができます。

SELECT     DISTINCT
           FIRST_VALUE ( t.owner )
             OVER ( ORDER BY t.num_rows DESC NULLS LAST )
                                                 owner,
           FIRST_VALUE ( t.table_name )
             OVER ( ORDER BY t.num_rows DESC NULLS LAST )
                                                 table_name,
           FIRST_VALUE ( t.num_rows )
             OVER ( ORDER BY t.num_rows DESC NULLS LAST )
                                                 num_rows
FROM       all_tables                            t
于 2008-12-29T16:00:55.413 に答える
1
select max(select count(*) from A union select count(*) from B...)

動作するはずです。

編集: 動的なものが必要な場合は、PL/SQL で各 "count(*)" サブクエリを使用して文字列を作成し (たとえば、USER_TABLES からテーブル名をリストする)、次のようにメインクエリを実行できます。

execute immediate 'select max('||subquery||')'
于 2008-12-24T07:14:21.113 に答える
0

これは、データベース テーブル内の最大行数を取得するクエリです。

select table_name, num_rows from USER_TABLES
where num_rows = (select  max(num_rows) from
(select table_name, num_rows from USER_TABLES));
于 2016-09-27T11:08:21.393 に答える