我需要一个查询来计算表中每个列的非空值的总数。由于我的表有数百列,我正在寻找一个只需要输入表名的解决方案。
也许使用以下结果:
select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='ORDERS';
获取列名,然后使用子查询为每个列名添加计数?另外一个复杂因素是我只对DB进行只读访问,因此我无法创建任何临时表。
稍微退出我的联赛,所以任何帮助都表示赞赏。
答案 0 :(得分:1)
在SQL中构建查询或使用电子表格。然后运行查询。
例如,假设您的列名很简单且没有特殊字符:
select replace('select ''[col]'', count([col]) from orders union all ',
'[col]', COLUMN_NAME
) as sql
from ALL_TAB_COLUMNS
where TABLE_NAME = 'ORDERS';
(当然,这可以适用于更复杂的列名,但我试图表明这个想法。)
然后复制代码,删除最终的union all
并运行它。
如果没有太多列,您可以将其放在一个字符串中:
select listagg(replace('select ''[col]'', count([col]) from orders',
'[col]', COLUMN_NAME
), ' union all '
) within group (order by column_name) as sql
from ALL_TAB_COLUMNS
where TABLE_NAME = 'ORDERS';
你也可以使用execute immediate
使用相同的查询,但这似乎有点过分。
答案 1 :(得分:0)
如果您对结果row-ar而不是column-ar感到满意:
SELECT 'SELECT ''dummy'', 0 FROM DUAL' FROM DUAL
UNION ALL
SELECT
' UNION ALL SELECT ''' ||
column_name ||
''', COUNT(' ||
column_name ||
') FROM ' ||
TABLE_NAME
FROM
all_tab_columns
WHERE
table_name = 'ORDERS'
这是一个编写SQL"的SQL。然后你可以复制并运行以获得你的答案。应该使结果集看起来像:
SELECT' dummy',0 FROM dual
UNION ALL SELECT' col1',COUNT(col1)FROM ORDERS
UNION ALL SELECT' col2',COUNT(col2)FROM ORDERS
...
如果您想要结果列-ar:
SELECT 'SELECT '
UNION ALL
SELECT
'COUNT(' ||
column_name ||
') as count_' ||
column_name ||
', ' ||
TABLE_NAME
FROM
all_tab_columns
WHERE
table_name = 'ORDERS'
UNION ALL
SELECT 'null as dummy_column FROM ORDERS'
应该使结果集看起来像:
选择
COUNT(col1)as count_col1,
COUNT(col2)as count_col2,
...
null as dummycoll FROM orders
警告:我没有安装oracle,我可以测试这些,它是从内存写的,可能需要一些调试
答案 2 :(得分:0)
这将生成SQL以获取列中的计数,并将使用非字母数字字符处理区分大小写的列名和列名:
SELECT 'SELECT '
|| LISTAGG(
'COUNT("' || column_name || '") AS "' || column_name || '"',
', '
) WITHIN GROUP ( ORDER BY column_id )
|| ' FROM "' || table_name || '"' AS sql
FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME = 'ORDERS'
GROUP BY TABLE_NAME;
或者,如果您有大量列生成超过4000个字符的字符串,则可以使用custom aggregation function to aggregate VARCHAR2
s into a CLOB
然后执行:
SELECT 'SELECT '
|| CLOBAgg( 'COUNT("' || column_name || '") AS "' || column_name || '"' )
|| ' FROM "' || table_name || '"' AS sql
FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME = 'ORDERS'
GROUP BY TABLE_NAME;
答案 3 :(得分:0)
在 Oracle 19 中(我在 Ora 12 中使用了类似的代码,也许也可以),这无需生成另一个要执行的选择:
select * from
(
select table_name, column_name,
to_number( extractvalue( xmltype(dbms_xmlgen.getxml('select count(to_char(substr('||column_name||',1,1))) c from '||table_name)) ,'/ROWSET/ROW/C')) count
from all_tab_columns where owner = user
)
--where table_name = 'MY_TABLE'
;
它将创建带有计数的 XML,从中提取当前计数。这里的 substr 和 to_char 函数用于提取第一个字符,因此它也适用于 CLOB 列