如何解决查询以查找各种组合 search 和 count 在单个查询 oracle 中
大家好,我遇到了一个要求,需要找出特定模式 (SCHEMA_A) 中列 (col1,col2,col3) 的计数,但这里有一个问题,我必须找出所有列的组合为了获得使用 VALID_FROM_DATE、VALID_FROM_DATE、TIMESTAMP 的表的数量,以下是更多详细信息
数据库 - Oracle 11g
表搜索 - DBA_TAB_COLUMNS
col1 - VALID_FROM_DATE
col2 - VALID_TO_DATE
col3 - 时间戳
组合搜索以及所有表的计数
combination 1
VALID_FROM_DATE + VALID_TO_DATE + TIMESTAMP
combination 2
VALID_FROM_DATE + VALID_TO_DATE
combination 3
VALID_FROM_DATE + TIMESTAMP
combination 4
VALID_TO_DATE + TIMESTAMP
combination 5
VALID_FROM_DATE
combination 6
VALID_TO_DATE
combination 7
TIMESTAMP
查询 - 我正在尝试
select count(distinct table_name) from DBA_TAB_COLUMNS
where owner='SCHEMA_A'
and column_name in ('VALID_FROM_DATE','VALID_TO_DATE','TIMESTAMP')
order by table_name;
但是如何在单个查询中实现上述组合(1-7)以捕获计数和总体百分比,是否有可能以最简单的方式实现单个查询块
percentage - round(100*ratio_to_report(count(*)) over (),2) percentage
有什么建议吗?
解决方法
我认为您正在寻找这样的东西。我正在使用多个 CTE 来分步拆分逻辑
- x_dba_tab_columns cte 只是模拟 dba_tab_columns 的测试数据
- all_tables cte 是一个不同的表列表
- table_w_cols cte 将每个表连接到按列过滤的 x_dba_tab_columns,如果该列存在则返回 1,如果不存在则返回 0
最后的select只是一个case语句来计算组合。
with x_dba_tab_columns (table_name,column_name)
AS
(
SELECT 'TABLE1','VALID_FROM_DATE' FROM DUAL UNION ALL
SELECT 'TABLE1','VALID_TO_DATE' FROM DUAL UNION ALL
SELECT 'TABLE1','TIMESTAMP' FROM DUAL UNION ALL
SELECT 'TABLE2','VALID_TO_DATE' FROM DUAL
),all_tables (table_name)
AS
(
SELECT DISTINCT table_name FROM x_dba_tab_columns
),table_w_cols (table_name,vfd,vtd,ts)
AS
(
SELECT
t.table_name,NVL2(vfd.table_name,1,0) vfd,NVL2(vtd.table_name,0) vtd,NVL2(ts.table_name,0) ts
FROM all_tables t
LEFT OUTER JOIN x_dba_tab_columns vfd ON vfd.table_name = t.table_name AND vfd.column_name = 'VALID_FROM_DATE'
LEFT OUTER JOIN x_dba_tab_columns vtd ON vtd.table_name = t.table_name AND vtd.column_name = 'VALID_TO_DATE'
LEFT OUTER JOIN x_dba_tab_columns ts ON ts.table_name = t.table_name AND ts.column_name = 'TIMESTAMP'
)
SELECT
table_name,CASE
WHEN (vfd = 1 AND vtd = 1 AND ts = 1) THEN 'combination 1'
WHEN (vfd = 1 AND vtd = 1) THEN 'combination 2'
WHEN (vfd = 1 AND ts = 1) THEN 'combination 3'
WHEN (vtd = 1 AND ts = 1) THEN 'combination 4'
WHEN (vfd = 1) THEN 'combination 5'
WHEN (ts = 1) THEN 'combination 7'
WHEN (vtd = 1) THEN 'combination 6'
END as combination
FROM table_w_cols;
TABLE1 combination 1
TABLE2 combination 6
,
我相信全外连接在这里会起作用。
这里的子查询被用来找出具有这些列的表,然后将结果连接起来为我们提供所有可能的组合。
在最后一步计算组合。
select case when vfd.table_name is not null then 'VALID_FROM_DATE' else null end VALID_FROM_DATE,case when vtd.table_name is not null then 'VALID_TO_DATE' else null end VALID_TO_DATE,case when ts.table_name is not null then 'TIMESTAMP' else null end TIMESTAMP_col,count(1) tables_cnt
from (select table_name from dba_tab_cols where column_name = 'VALID_FROM_DATE') vfd -- tables with 'VALID_FROM'
full outer join (select table_name from dba_tab_cols where column_name = 'VALID_TO_DATE') vtd -- tables with 'VALID_TO'
on vfd.table_name = vtd.table_name
full outer join (select table_name from dba_tab_cols where column_name = 'TIMESTAMP') ts -- tables with 'TIMESTAMP'
on vfd.table_name = ts.table_name
where vfd.table_name is not null
or vtd.table_name is not null
or ts.table_name is not null
group by case when vfd.table_name is not null then 'VALID_FROM_DATE' else null end,case when vtd.table_name is not null then 'VALID_TO_DATE' else null end,case when ts.table_name is not null then 'TIMESTAMP' else null end
我在这里使用的子查询只是为了提高可读性。如果有人骂你这里的子查询有问题,你可以使用以下版本
select case when vfd.table_name is not null then 'VALID_FROM_DATE' else null end VALID_FROM_DATE,count(1) tables_cnt
from user_tab_cols vfd -- tables with 'VALID_FROM'
full outer join user_tab_cols vtd -- tables with 'VALID_TO'
on vfd.table_name = vtd.table_name
and vfd.column_name = 'VALID_FROM_DATE'
and vtd.column_name = 'VALID_TO_DATE'
full outer join user_tab_cols ts -- tables with 'TIMESTAMP'
on vfd.table_name = ts.table_name
and vfd.column_name = 'VALID_FROM_DATE'
and ts.column_name = 'TIMESTAMP'
where vfd.column_name = 'VALID_FROM_DATE'
or vtd.column_name = 'VALID_TO_DATE'
or ts.column_name = 'TIMESTAMP'
group by case when vfd.table_name is not null then 'VALID_FROM_DATE' else null end,case when ts.table_name is not null then 'TIMESTAMP' else null end;
如果出现性能问题,在 dba_tab_cols 的 column_name 上添加索引可能会有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。