簡體   English   中英

如何選擇包含最大不同值的列名? - 甲骨文 SQL

[英]How to select the column name that contains maximum number of distinct values? - Oracle 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' 

這樣做是檢索表中每列的名稱以及每列中的行數。

我需要做的是檢索每列中存在的不同值的數量,然后最終確定哪一列具有最大數量的不同條目。 鑒於我當前的查詢,我將如何去做?

有沒有更好的方法來實現我想做的事情? 是否需要動態 SQL?

您可以使用XMLQUERY來獲取所需的結果。

Oracle 數據設置:

 SQL> CREATE TABLE TEST_SO (COL1 NUMBER, COL2 VARCHAR(20)); Table created. SQL> SQL> INSERT INTO TEST_SO (COL1,COL2) VALUES (1, 'TEJASH'); 1 row created. SQL> INSERT INTO TEST_SO (COL1,COL2) VALUES (2, 'TEJASH1'); 1 row created. SQL> INSERT INTO TEST_SO (COL1,COL2) VALUES (3, 'TEJASH2'); 1 row created. SQL> INSERT INTO TEST_SO (COL1,COL2) VALUES (2, 'TEJASH3'); 1 row created. SQL> INSERT INTO TEST_SO (COL1,COL2) VALUES (2, 'TEJASH'); 1 row created. SQL>

現在, COL2有 4 個不同的值, COL1有 3 個不同的值。 使用以下查詢獲取COL2和 4(因為它大於 3( COL1不同值))作為其中的不同值。

您的查詢:

 SQL> SELECT 2 C.COLUMN_NAME, 3 TO_NUMBER(XMLQUERY('/ROWSET/ROW/C/text()' 4 PASSING XMLTYPE(DBMS_XMLGEN.GETXML( 5 'select count(distinct "' 6 || C.COLUMN_NAME 7 || '") as c ' 8 || 'from "' 9 || C.TABLE_NAME 10 || '"')) RETURNING CONTENT)) AS DISTINCT_VALS 11 FROM USER_TAB_COLUMNS C 12 WHERE C.TABLE_NAME = 'TEST_SO' 13 ORDER BY DISTINCT_VALS DESC NULLS LAST 14 FETCH FIRST ROW WITH TIES; COLUMN_NAME DISTINCT_VALS --------------- ------------- COL2 4 SQL>

干杯!!

自從

  • 您已准備好使用 all_% 視圖中的 num_rows 並且
  • 如果您收集了統計數據並且
  • 一些可能的差異是可以接受的,您可以使用從 all_tab_col_statistics 收集的統計數據數據庫。

像這樣。

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM