如何将所有记录合并为一行 |甲骨文 SQL |
How to combine all records into one row | ORACLE SQL |
我一直在尝试这样做,但无法使用 list_agg
我有 1 个 table 其中包含所有 table 个名字
Table 姓名:get_tables
下面是 get_tables
中的所有 table 个名字。获取 tables 作为名为 tbl_names
的列
tbl_names
--------------
EMP_1
EMP_2
STUD_1
STUD_2
DEMO_1
STUDENT_DETAILS
我写了一个综合查询来获取所有 tables 计数
select 'SELECT ' || '''' || tbl_names || '''' || ' AS TBL , COUNT(*) as CNT FROM from tbl_names || 'union' from get_tables;
基本上我生成下面的查询作为上面查询的输出
0 SELECT 'EMP_1' AS TBL , COUNT(*) from EMP_1 union
1 SELECT 'EMP_2' AS TBL , COUNT(*) from EMP_2 union
2 SELECT 'STUD_1' AS TBL , COUNT(*) from STUD_1 union
3 SELECT 'STUD_2' AS TBL , COUNT(*) from STUD_1 union
4 SELECT 'DEMO_1' AS TBL , COUNT(*) from DEMO_1 union
5 SELECT 'STUDENT_DETAILS' AS TBL , COUNT(*) from STUDENT_DETAILS union
现在我首先要查询的两件事是记录
需要将所有组合为一个查询并从最后一行删除最后一个关键字 union
并替换为 ';'
所以这个生成的查询我可以 运行 从我的 python 脚本中一次性获得所有 table 计数 table name
预期输出:
TABLE COUNT
EMP_1 10
EMP_2 20
STUD_1 40
STUD_2 50
DEMO_1 50
STUDENT_DETAILS 100
为什么不直接查询 all_tables table(或 user_tables 或 dba_tables),它已经保存了每个 table 的行数?
SELECT TABLE_NAME, NUM_ROWS
FROM ALL_TABLES;
这里介绍一种方法,用LISTAGG来说明方法。如果 table 太多,您将需要一种不同的聚合方式(例如 XMLAGG),但这是一个不同的问题 - 您可以在 SO 上找到数百个相关问题。
最好使用UNION ALL而不是UNION,但如果你坚持只使用UNION,你可以自己修改解决方案。使用 LISTAGG,但不要在要聚合的标记中包含 UNION [ALL];相反,将其用作 分隔符 !
为了更容易阅读输出,我还在分隔符中包含了一个换行符;除了调试外不需要。在您对查询按预期工作感到满意后,您可以选择将其删除。
另外,我也懒得在末尾连接一个分号;你可以自己添加。
注意 - 输出是单行,意味着包含换行符的单个字符串(因此显示为多行文本)。它没有分布在多个 行 上,它只是一行中单个字符串中的几行。
EDIT 再次查看,我发现您的个别 SELECT 语句不正确(它们显示关键字“from”两次,所有 SELECT 语句正在计算 get_tables
table 中的行数,而不是每个 table 中的行数,也许还有其他错误)。我会让你改正所有这些错误;它们与您问题的主要主题无关,该主题是关于以所需方式汇总陈述 - 无论正确与否。
结束编辑(在答案底部进一步编辑)
with get_tables (tbl_names) as (
select 'EMP_1' from dual union all
select 'EMP_2' from dual union all
select 'STUD_1' from dual union all
select 'STUD_2' from dual union all
select 'STUD_3' from dual union all
select 'STUDENT_DETAILS' from dual
)
-- end of sample data, for testing only; remove WITH clause
-- and use your actual table and column names.
select listagg('SELECT ' || '''' || tbl_names || '''' ||
' AS TBL , COUNT(*) as CNT FROM from tbl_names',
' union all' || chr(10))
within group (order by tbl_names) as sql_str
from get_tables;
SQL_STR
----------------------------------------------------------------------------------
SELECT 'EMP_1' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'EMP_2' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUDENT_DETAILS' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUD_1' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUD_2' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUD_3' AS TBL , COUNT(*) as CNT FROM from tbl_names
第二次编辑
OP 的用例需要生成 CLOB,因此 LISTAGG 将不起作用。以下是如何修改查询以使其适用于 CLOB 输出。我同时更正了声明 - 在第一个代码块之前查看我的第一个编辑。
为了确保它能正常工作,我在我的架构中为 ALL_TABLES
视图编写了它; table 个名字在名为 TABLE_NAME
的列中。 OP 应该为他的用例更改这些名称。
select regexp_replace(
xmlcast(xmlagg(xmlelement(e,
'select ''' || table_name || ''' as tbl, count(*) as cnt from '
|| table_name, ' union all ' || chr(10))) as clob),
' union all ' || chr(10) ||'$', ';')
as sql_string
from all_tables;
结束第二次编辑
我一直在尝试这样做,但无法使用 list_agg
我有 1 个 table 其中包含所有 table 个名字
Table 姓名:get_tables
下面是 get_tables
中的所有 table 个名字。获取 tables 作为名为 tbl_names
tbl_names
--------------
EMP_1
EMP_2
STUD_1
STUD_2
DEMO_1
STUDENT_DETAILS
我写了一个综合查询来获取所有 tables 计数
select 'SELECT ' || '''' || tbl_names || '''' || ' AS TBL , COUNT(*) as CNT FROM from tbl_names || 'union' from get_tables;
基本上我生成下面的查询作为上面查询的输出
0 SELECT 'EMP_1' AS TBL , COUNT(*) from EMP_1 union
1 SELECT 'EMP_2' AS TBL , COUNT(*) from EMP_2 union
2 SELECT 'STUD_1' AS TBL , COUNT(*) from STUD_1 union
3 SELECT 'STUD_2' AS TBL , COUNT(*) from STUD_1 union
4 SELECT 'DEMO_1' AS TBL , COUNT(*) from DEMO_1 union
5 SELECT 'STUDENT_DETAILS' AS TBL , COUNT(*) from STUDENT_DETAILS union
现在我首先要查询的两件事是记录
需要将所有组合为一个查询并从最后一行删除最后一个关键字 union
并替换为 ';'
所以这个生成的查询我可以 运行 从我的 python 脚本中一次性获得所有 table 计数 table name
预期输出:
TABLE COUNT
EMP_1 10
EMP_2 20
STUD_1 40
STUD_2 50
DEMO_1 50
STUDENT_DETAILS 100
为什么不直接查询 all_tables table(或 user_tables 或 dba_tables),它已经保存了每个 table 的行数?
SELECT TABLE_NAME, NUM_ROWS
FROM ALL_TABLES;
这里介绍一种方法,用LISTAGG来说明方法。如果 table 太多,您将需要一种不同的聚合方式(例如 XMLAGG),但这是一个不同的问题 - 您可以在 SO 上找到数百个相关问题。
最好使用UNION ALL而不是UNION,但如果你坚持只使用UNION,你可以自己修改解决方案。使用 LISTAGG,但不要在要聚合的标记中包含 UNION [ALL];相反,将其用作 分隔符 !
为了更容易阅读输出,我还在分隔符中包含了一个换行符;除了调试外不需要。在您对查询按预期工作感到满意后,您可以选择将其删除。
另外,我也懒得在末尾连接一个分号;你可以自己添加。
注意 - 输出是单行,意味着包含换行符的单个字符串(因此显示为多行文本)。它没有分布在多个 行 上,它只是一行中单个字符串中的几行。
EDIT 再次查看,我发现您的个别 SELECT 语句不正确(它们显示关键字“from”两次,所有 SELECT 语句正在计算 get_tables
table 中的行数,而不是每个 table 中的行数,也许还有其他错误)。我会让你改正所有这些错误;它们与您问题的主要主题无关,该主题是关于以所需方式汇总陈述 - 无论正确与否。
结束编辑(在答案底部进一步编辑)
with get_tables (tbl_names) as (
select 'EMP_1' from dual union all
select 'EMP_2' from dual union all
select 'STUD_1' from dual union all
select 'STUD_2' from dual union all
select 'STUD_3' from dual union all
select 'STUDENT_DETAILS' from dual
)
-- end of sample data, for testing only; remove WITH clause
-- and use your actual table and column names.
select listagg('SELECT ' || '''' || tbl_names || '''' ||
' AS TBL , COUNT(*) as CNT FROM from tbl_names',
' union all' || chr(10))
within group (order by tbl_names) as sql_str
from get_tables;
SQL_STR
----------------------------------------------------------------------------------
SELECT 'EMP_1' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'EMP_2' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUDENT_DETAILS' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUD_1' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUD_2' AS TBL , COUNT(*) as CNT FROM from tbl_names union all
SELECT 'STUD_3' AS TBL , COUNT(*) as CNT FROM from tbl_names
第二次编辑
OP 的用例需要生成 CLOB,因此 LISTAGG 将不起作用。以下是如何修改查询以使其适用于 CLOB 输出。我同时更正了声明 - 在第一个代码块之前查看我的第一个编辑。
为了确保它能正常工作,我在我的架构中为 ALL_TABLES
视图编写了它; table 个名字在名为 TABLE_NAME
的列中。 OP 应该为他的用例更改这些名称。
select regexp_replace(
xmlcast(xmlagg(xmlelement(e,
'select ''' || table_name || ''' as tbl, count(*) as cnt from '
|| table_name, ' union all ' || chr(10))) as clob),
' union all ' || chr(10) ||'$', ';')
as sql_string
from all_tables;
结束第二次编辑