Sql 如何选择包含最大不同值数的列名?-软件开发工程师

Sql 如何选择包含最大不同值数的列名?-软件开发工程师,sql,oracle,distinct,dynamic-sql,Sql,Oracle,Distinct,Dynamic Sql,以下是我当前的查询: SELECT c.COLUMN_NAME, t.NUM_ROWS FROM ALL_TAB_COLUMNS c INNER JOIN ALL_TABLES t ON t.OWNER = c.OWNER AND t.TABLE_NAME = c.TABLE_NAME WHERE c.TABLE_NAME='MY_TABLE_NAME' AND c.OWNER = 'MY_SCHEMA_NAME' 这样做的目的是检索表中每列的名称以及每列中的行数 我需要做的是检索每列中存在

以下是我当前的查询:

SELECT c.COLUMN_NAME, t.NUM_ROWS
FROM ALL_TAB_COLUMNS c
INNER JOIN ALL_TABLES t ON t.OWNER = c.OWNER AND t.TABLE_NAME = c.TABLE_NAME
WHERE c.TABLE_NAME='MY_TABLE_NAME'
AND c.OWNER = 'MY_SCHEMA_NAME' 
这样做的目的是检索表中每列的名称以及每列中的行数

我需要做的是检索每列中存在的不同值的数量,然后最终确定哪列具有最大数量的不同条目。鉴于我目前的疑问,我将如何着手进行这项工作

有没有更好的方法来实现我想做的事情?是否需要动态SQL?

您可以使用XMLQUERY获取所需的结果

Oracle数据设置:

现在,COL2有4个不同的值,COL1有3个不同的值。 使用以下查询获取COL2和COL4,因为它大于COL1中作为其不同值的3个不同值

您的查询:

干杯

您可以使用XMLQUERY获取所需的结果

Oracle数据设置:

现在,COL2有4个不同的值,COL1有3个不同的值。 使用以下查询获取COL2和COL4,因为它大于COL1中作为其不同值的3个不同值

您的查询:

干杯

您已准备好使用“所有”视图中的num_行,并且 如果你收集了统计数据并 一些可能的差异是可以接受的,您可以使用统计数据数据库从所有统计数据中收集的数据。 像这样

select num_distinct, column_name 
  from all_tab_col_statistics
 where table_name = 'TABLE_NAME_UPPERCASE'
 order by num_distinct desc
 fetch first row with ties;
同样,当一些公差可以接受时,请使用此选项。 虽然通常根据DBA定期收集表统计数据,但收集到的数据与实际值之间可能存在某种差距。

您已准备好使用“所有”视图中的num_行,并且 如果你收集了统计数据并 一些可能的差异是可以接受的,您可以使用统计数据数据库从所有统计数据中收集的数据。 像这样

select num_distinct, column_name 
  from all_tab_col_statistics
 where table_name = 'TABLE_NAME_UPPERCASE'
 order by num_distinct desc
 fetch first row with ties;
同样,当一些公差可以接受时,请使用此选项。
虽然通常根据DBA定期收集表统计数据,但收集的数据与实际值之间可能存在某种差距。

对于单个表,您也可以执行以下过程:

DECLARE

    CURSOR Cols IS
    SELECT COLUMN_NAME 
    FROM USER_TAB_COLUMNS 
    WHERE TABLE_NAME = 'MY_TABLE_NAME' 
    ORDER BY COLUMN_ID;

    cur INTEGER := DBMS_SQL.OPEN_CURSOR;
    columnCount INTEGER := 0;
    describeColumns DBMS_SQL.DESC_TAB2;
    res INTEGER;
    distinctValues NUMBER;
    m NUMBER := -1;
    c INTEGER := 0;

    sqlstr VARCHAR2(30000);

BEGIN

    FOR aCol IN Cols LOOP
        sqlstr := sqlstr || ',COUNT(DISTINCT '||aCol.COLUMN_NAME||') AS '||aCol.COLUMN_NAME;
    END LOOP;
    sqlstr := REGEXP_REPLACE(sqlstr, '^,', 'SELECT ')||' FROM MY_TABLE_NAME';

    DBMS_SQL.PARSE(cur, sqlStr, DBMS_SQL.NATIVE);
    DBMS_SQL.DESCRIBE_COLUMNS2(cur, columnCount, describeColumns);

    FOR i IN 1..columnCount LOOP
        DBMS_SQL.DEFINE_COLUMN(cur, i, distinctValues);
    END LOOP;
    res := DBMS_SQL.EXECUTE(cur);

    res := DBMS_SQL.FETCH_ROWS(cur); -- no loop required as you get always exactly one row
    FOR i IN 1..columnCount LOOP
        DBMS_SQL.COLUMN_VALUE(cur, i, distinctValues);
        IF distinctValues > m THEN
            m := distinctValues;
            c := i;
        END IF;
        DBMS_OUTPUT.PUT_LINE ( describeColumns(i).col_name ||': '|| distinctValues );
    END LOOP;
    DBMS_OUTPUT.PUT_LINE ( 'Max distinct values at '||describeColumns(c).col_name ||': '|| m );

END;

对于单个表,您也可以执行如下步骤:

DECLARE

    CURSOR Cols IS
    SELECT COLUMN_NAME 
    FROM USER_TAB_COLUMNS 
    WHERE TABLE_NAME = 'MY_TABLE_NAME' 
    ORDER BY COLUMN_ID;

    cur INTEGER := DBMS_SQL.OPEN_CURSOR;
    columnCount INTEGER := 0;
    describeColumns DBMS_SQL.DESC_TAB2;
    res INTEGER;
    distinctValues NUMBER;
    m NUMBER := -1;
    c INTEGER := 0;

    sqlstr VARCHAR2(30000);

BEGIN

    FOR aCol IN Cols LOOP
        sqlstr := sqlstr || ',COUNT(DISTINCT '||aCol.COLUMN_NAME||') AS '||aCol.COLUMN_NAME;
    END LOOP;
    sqlstr := REGEXP_REPLACE(sqlstr, '^,', 'SELECT ')||' FROM MY_TABLE_NAME';

    DBMS_SQL.PARSE(cur, sqlStr, DBMS_SQL.NATIVE);
    DBMS_SQL.DESCRIBE_COLUMNS2(cur, columnCount, describeColumns);

    FOR i IN 1..columnCount LOOP
        DBMS_SQL.DEFINE_COLUMN(cur, i, distinctValues);
    END LOOP;
    res := DBMS_SQL.EXECUTE(cur);

    res := DBMS_SQL.FETCH_ROWS(cur); -- no loop required as you get always exactly one row
    FOR i IN 1..columnCount LOOP
        DBMS_SQL.COLUMN_VALUE(cur, i, distinctValues);
        IF distinctValues > m THEN
            m := distinctValues;
            c := i;
        END IF;
        DBMS_OUTPUT.PUT_LINE ( describeColumns(i).col_name ||': '|| distinctValues );
    END LOOP;
    DBMS_OUTPUT.PUT_LINE ( 'Max distinct values at '||describeColumns(c).col_name ||': '|| m );

END;

Hm此运行,但由于某些原因,我得到一个空结果集。您在上面的查询中更改了表名吗?是的,将表名更改为我的表。Hm此运行,但我得到一个空结果集。您在上面的查询中更改了表名吗?是的,将表名更改为我的表。谢谢,这是我正在寻找的。是否也可以仅对number/integer类型的列执行此操作?是否要以某种方式限制列类型?@asdfghjkl9999您可以通过表名和列名将其与所有_tab_cols连接起来。从那里获取数据类型谢谢,这就是我要找的。是否也可以仅对number/integer类型的列执行此操作?是否要以某种方式限制列类型?@asdfghjkl9999您可以通过表名和列名将其与所有_tab_cols连接起来。然后从那里获取数据类型