查询以查找各种组合 search 和 count 在单个查询 oracle 中

如何解决查询以查找各种组合 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?