【问题标题】:Manage null values of xmlagg管理 xmlagg 的空值
【发布时间】:2019-09-16 17:48:25
【问题描述】:

我有以下结构的查询:

SELECT 'SELECT ' || col_list || ' from schema.table;' from( Select table_name,  rtrim(xmlagg(xml element(e,  Case when datatype in ('blob', 'timestamp') then null else column_name end , ', ').extract('//text()') order by c_id).getclobval(), ', ' ) col_list from all_tab_cols where schema ='schema' and table in ('t1', 't2') group by table_name)

当前两列、第四列和第六列是 blob 或时间戳类型时,这会给我输出:

SELECT ,  ,  third_col, , fifth_col, from schema.table;

如何修改查询以使其提供:

SELECT third_col,  fifth_col from schema.table;

这个生成的 select 语句进一步存储为 spark 数据帧中的一行(我使用的是 Scala)。因此,如果我们可以通过正则表达式或替换子字符串来修改查询,那也可以解决,我也愿意接受这些建议,但如果我不必以这种方式侵入并管理它,我将不胜感激在查询方面本身。

【问题讨论】:

    标签: xml oracle scala apache-spark aggregation


    【解决方案1】:

    我认为您过于复杂了;根本不包括这些列,通过在where 子句中过滤掉它们:

    ...
      from all_tab_cols
      where owner = 'schema'
      and table_name in ('t1', 't2')
      and data_type != 'BLOB'
      and data_type not like 'TIMESTAMP%'
      group by table_name
    )
    

    然后您可以删除 case 表达式。

    你也可以简化一下:

    select 'SELECT '
      || rtrim(xmlagg(xmlelement(e, column_name, ', ').extract('//text()') order by column_id).getclobval(), ', ' )
      || ' FROM ' || owner || '.' || table_name || ';'
    from all_tab_cols
    where owner = 'schema'
    and table_name in ('t1', 't2')
    and data_type != 'BLOB'
    and data_type not like 'TIMESTAMP%'
    group by owner, table_name;
    

    db<>fiddle

    【讨论】:

    • 我不能使用 listagg 因为聚合的列列表超过 4000 字节,其次我不能使用 where 子句,因为与列表一起我得到了表名。我刚刚在嵌套选择中提供了聚合列列表,但是有多个表,每个表我们都会生成它的串联列表。因此,如果我们使用 where 子句,它将排除该表的整个聚合列列表,而不仅仅是排除 blob 和时间戳类型的特定列。
    • 让我更新查询它的实际外观。当我们使用 listagg 时,如果它为 null,聚合列会忽略它,但 xmlagg 不是这种情况。这就是为什么我正在寻找处理它的最佳方法,以便只有特定的列类型才会从 select 语句中排除。
    • 我不明白你的第二点。它仅排除具有这些类型的列,而不排除该表的任何其他列或整个表。
    • 你可以先看看。更新的查询。它试图在嵌套选择中获取表名及其各自的连接列名。也就是说,如果 t1 具有 varchar、number 和 blob 类型的三列,则嵌套查询应该返回 t1,col_list 为 c1、c2。如果你放一个 where 子句说 datatype not in('blob') 它根本不会返回那个 table_name 和 col_list。如果我有什么不对的地方,请你写一个示例查询并演示一下。
    • 你是对的。它有效,我的坏。我假设如果我尝试在 where 子句中使用 not in ,它将排除具有排除类型列的整个表。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 2019-09-23
    相关资源
    最近更新 更多