Nếu bạn đồng ý với một hàng đặt kết quả cho mỗi cột, bạn có thể điều chỉnh trò ảo thuật XML này :
select owner, table_name, column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as c
from all_tab_columns
where owner = '<your table owner>'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2', 'NCHAR', 'NVARCHAR2');
... liệt kê tất cả các kiểu dữ liệu bạn cần để có thể đếm; thực sự đó là để loại trừ những thứ không thể xử lý distinct
như CLOB, nhưng vì bạn có thể có các bảng lồng nhau, v.v. nên có lẽ sẽ đơn giản hơn để liệt kê những người bạn làm muốn và mong đợi có thể đếm được.
dbms_xmlgen()
cuộc gọi chuyển đổi kết quả của select count(distinct ...) ...
truy vấn, được tạo động một cách hiệu quả, thành một cấu trúc XML và sau đó bạn có thể lấy ra từ đó bằng XMLQuery()
(thay vì extractvalue()
không dùng nữa trong câu trả lời được liên kết).
Dưới dạng bản demo rất nhanh:
create table t42 (id number, str varchar2(20));
insert into t42 values (1, 'Test');
insert into t42 values (2, 'Test');
insert into t42 values (3, 'Test 2');
insert into t42 values (3, null);
select owner, table_name, column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as c
from all_tab_columns
where owner = 'MY_SCHEMA'
and table_name = 'T42'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2', 'NCHAR', 'NVARCHAR2');
OWNER TABLE_NAME COLUMN_NAME C
--------------- --------------- --------------- ----------
MY_SCHEMA T42 ID 3
MY_SCHEMA T42 STR 2
count()
hàm bỏ qua các giá trị null, vì vậy, để đếm những giá trị bạn phải chuyển đổi chúng, ví dụ:với
count(case when <your_column> is null then 1 end)
Bạn bao gồm điều đó ở đây với mệnh đề XMLQuery thứ hai:
select owner, table_name, column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as distinct_count,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(case when "' || column_name || '" is null then 1 end) as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as null_count
from all_tab_columns
where owner = 'MY_SCHEMA'
and table_name = 'T42'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2',
'NCHAR', 'NVARCHAR2');
OWNER TABLE_NAME COLUMN_NAME DISTINCT_COUNT NULL_COUNT
--------------- --------------- --------------- -------------- ----------
MY_SCHEMA T42 ID 3 0
MY_SCHEMA T42 STR 2 1
hoặc với một XMLTable duy nhất trích xuất cả hai giá trị cột từ XML đã tạo, được sửa đổi để thực hiện cả hai giá trị cùng một lúc:
select a.owner, a.table_name, a.column_name,
x.distinct_count, x.null_count
from
(
select owner, table_name, column_name,
dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c1,'
|| 'count(case when "' || column_name || '" is null then 1 end) as c2 '
|| 'from "' || owner || '"."' || table_name || '"') as xml_clob
from all_tab_columns
where owner = 'MY_SCHEMA'
and table_name = 'T42'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2',
'NCHAR', 'NVARCHAR2')
) a
cross join xmltable (
'/ROWSET/ROW'
passing xmltype(a.xml_clob)
columns distinct_count number path 'C1',
null_count number path 'C2'
) x;
OWNER TABLE_NAME COLUMN_NAME DISTINCT_COUNT NULL_COUNT
--------------- --------------- --------------- -------------- ----------
MY_SCHEMA T42 ID 3 0
MY_SCHEMA T42 STR 2 1