Определить таблицу с максимальным количеством строк в Oracle - PullRequest
5 голосов
/ 24 декабря 2008

У меня есть набор таблиц в Oracle, и я хотел бы определить таблицу, которая содержит максимальное количество строк.

Так что, если A имеет 200 строк, B имеет 345 строк, а C имеет 120 строк, я хочу иметь возможность идентифицировать таблицу B.

Можно ли выполнить простой запрос для достижения этой цели?

Редактировать: Есть более 100 таблиц, поэтому я ищу что-то общее.

Ответы [ 7 ]

12 голосов
/ 24 декабря 2008

Учитывая, что вы сказали, что используете 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; 

и вы увидите, какие самые большие.

4 голосов
/ 24 декабря 2008

Таблица в вашей схеме с максимальным количеством строк:

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 ....') чрезвычайно гибок.

3 голосов
/ 24 декабря 2008

Вот еще один метод, который, вероятно, будет намного медленнее, чем просто получение 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;
    /
1 голос
/ 30 декабря 2008

Дэвид Олдридж правильно указывает, что запрос 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
1 голос
/ 29 декабря 2008

Вы можете получить тот же результат с одним тралом данных, например:

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
1 голос
/ 24 декабря 2008
select max(select count(*) from A union select count(*) from B...)

должно работать.

edit: если вам нужно что-то динамическое, вы можете построить строку в PL / SQL с каждым подзапросом «count (*)» (например, перечислить имена таблиц из USER_TABLES), а затем выполнить основной запрос с помощью:

execute immediate 'select max('||subquery||')'
0 голосов
/ 27 сентября 2016

Это запрос для получения максимального числа строк в таблице базы данных.

select table_name, num_rows from USER_TABLES
where num_rows = (select  max(num_rows) from
(select table_name, num_rows from USER_TABLES));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...