Oracle - 每列的不同值

时间:2012-12-13 12:44:40

标签: oracle distinct

我知道有类似主题的讨论,但这有点不同

我需要在Oracle中使用查询来获取给定表的值对(列名,不同值的计数)。

示例:来自此表

|   ID     |    NAME    |    AGE   |
____________________________________
|   01     |    MARY    |    10    |
|   02     |    MAX     |    30    |
|   03     |    ALICE   |    30    |
|   04     |    MARY    |    20    |
|   05     |    JOE     |    10    |
____________________________________

我需要

|   COLUNL |    DIST. VALUES    |
________________________________
|   ID     |    5       |
|   NAME   |    4       | 
|   AGE    |    3       |
________________________________

问题是我不知道表的结构。我将只有表名,我需要为每个表生成这些信息。 任何想法?????

4 个答案:

答案 0 :(得分:6)

每列的不同值的数量存储在系统表USER_TAB_COL_STATISTICS中。通过调用过程DBMS_STATS.GATHER_TABLE_STATS收集统计数据。问你的DBA,它应该已经设置好了。

CREATE TABLE mytable (id NUMBER, name VARCHAR2(10), age NUMBER);
INSERT INTO mytable VALUES (01, 'MARY',  10);
INSERT INTO mytable VALUES (02, 'MAX',   30);
INSERT INTO mytable VALUES (03, 'ALICE', 30);
INSERT INTO mytable VALUES (04, 'MARY',  20);
INSERT INTO mytable VALUES (04, 'JOE',   10);
COMMIT;
EXECUTE dbms_stats.gather_table_stats(user, 'MYTABLE');

SELECT table_name, column_name, num_distinct
  FROM user_tab_col_statistics
 WHERE table_name = 'MYTABLE';

TABLE_NAME COLUMN_NAME NUM_DISTINCT
MYTABLE    ID          4
MYTABLE    NAME        4
MYTABLE    AGE         3  

答案 1 :(得分:0)

您可以使用UNION,例如......

执行此操作
 SELECT 'ID', Count(Distinct ID) As ValueCount From TableName
 UNION
 SELECT 'NAME', Count(Distinct NAME) From TableName
 UNION
 SELECT 'AGE', Count(Distinct AGE) From TableName

[编辑]
另一种方法是分析表格,例如......

ANALYZE TABLE TABLENAME COMPUTE STATISTICS;

然后......

SELECT COLUMN_NAME, NUM_DISTINCT FROM USER_TAB_COLUMNS WHERE TABLE_NAME = 'TABLENAME'

答案 2 :(得分:0)

您可以对UNION ALL使用UNPIVOT查询,然后计算数据:

select col col_name,
  count(distinct value)
from
(
  select cast(id as varchar(10)) value, 'id' col
  from yourtable
  union all
  select name value, 'name' col
  from yourtable
  union all
  select cast(age as varchar(10)) value, 'age' col
  from yourtable
) 
group by col

请参阅SQL Fiddle with Demo

如果您使用的是Oracle 11g +,那么您可以使用UNPIVOT函数执行此操作:

select col, count(distinct value) CountofValue
from
(
  select cast(id as varchar(10)) id, 
    name, 
    cast(age as varchar(10)) age
  from yourtable
) 
unpivot
(
  value
  for col in (id, name, age)
) 
group by col

请参阅SQL Fiddle with Demo

答案 3 :(得分:0)

在想法之下,你应该稍微努力一下:

create table stats_on_tables(
    date_id date, 
    table_name varchar2(32), 
    col_name varchar2(32), 
    cnt_distinct number
);

然后使用参数p table_name创建一个过程:

for n in (select column_name from user_tab_columns where table_name = p_table_name)
loop
  execute immediate 
    'insert into stats_on_table (date_id, table_name, col_name, cnt_distinct)
     values (sysdate, '||p_table_name||','||n.column_name||', (
     select count(distinct '||n.column_name||') from '||p_table_name||' ))';
end loop;
commit;