在一个查询中计算多个表的行数

Posted

技术标签:

【中文标题】在一个查询中计算多个表的行数【英文标题】:Count number of rows for multiple tables in one query 【发布时间】:2016-03-31 19:38:42 【问题描述】:

所以我有大量属于某个类别的表格。这些表都以 B1T 开头(所以 B1T00001、B1T0002 等)。我的任务是提供有关这组表格的一些信息。

这是我的初始 SQL,用于计算有多少 B1T 表。

select obj_nm from od_md_obj
where proj_id = '6' and obj_nm like ('%B1T%')and obj_typ_id = '9';

这将返回大约 260 个表。我正在尝试计算所有组合表的行数。查询可以按表打破它的计数,可能对总计数使用汇总;或者只需对所有内容进行一次计数。

我尝试在搜索中查看一些解决方案,但考虑到我要查询的表的数量,它需要一些繁琐的代码。

任何帮助将不胜感激!

我目前正在使用 SQL 开发人员。

【问题讨论】:

太糟糕了。我有一个 SQL Server 解决方案。 :/欣赏思路哈哈 看起来您正在为糟糕的数据库设计而苦苦挣扎。一个表应该代表一个实体,比如用户、订单、供应商、成员资格等等。不会有两个用户表或两个订单表。如果有更多数据,您可以将数据添加到一个表中,而不是添加一个新表。但这似乎是您的数据库中的情况。为什么不只有一张 B1T 表?那么计数记录将非常简单。 【参考方案1】:

创建一个将为您生成查询的查询。 例如这个查询:

select 'SELECT ''' || table_name || ''' as table_name, count(*) As con ' ||
       'FROM ' || table_name || 
        CASE WHEN lead(table_name) OVER (order by table_name ) IS NOT NULL 
        THEN ' UNION ALL ' END
from user_tables 
where table_name like 'B1T%'
;

会产生这样的结果:

SELECT 'B1T00000' as table_name, count(*) As con FROM B1T00000 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00001' as table_name, count(*) As con FROM B1T00001 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00002' as table_name, count(*) As con FROM B1T00002 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00003' as table_name, count(*) As con FROM B1T00003 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00004' as table_name, count(*) As con FROM B1T00004 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00005' as table_name, count(*) As con FROM B1T00005 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00006' as table_name, count(*) As con FROM B1T00006 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00007' as table_name, count(*) As con FROM B1T00007 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00008' as table_name, count(*) As con FROM B1T00008 UNION ALL  
....
....
....
SELECT 'B1T00257' as table_name, count(*) As con FROM B1T00257 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00258' as table_name, count(*) As con FROM B1T00258 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00259' as table_name, count(*) As con FROM B1T00259 UNION ALL                                                                                                                                                                                                                                                  
SELECT 'B1T00260' as table_name, count(*) As con FROM B1T00260

现在只需复制此结果,将其粘贴到您的客户端(SQL-Developer 等)并运行它。 你会得到想要的结果:

TABLE_NAME        CON
---------- ----------
B1T00000           65 
B1T00001           66 
B1T00002           67 
B1T00003           68 
B1T00004           69
...
...
...
B1T00256          321 
B1T00257          322 
B1T00258          323 
B1T00259          324 
B1T00260          325 

 261 rows selected  

【讨论】:

这与我的 SQL Server 解决方案非常相似。不过,我已经忘记了我所有的 Oracle 语法!干得好!【参考方案2】:

Oracle 的哪个版本? Oracle 12 允许在 with 子句中使用函数;所以一个可能的解决方案是

WITH FUNCTION count_rows(t_name IN VARCHAR2) RETURN NUMBER  
AS  
   l_rows NUMBER;  
BEGIN  
   EXECUTE IMMEDIATE 'SELECT COUNT(*)  FROM ' || t_name INTO l_rows;  
   RETURN l_rows;  
END;  
SELECT table_name, count_rows(table_name) as row_count
   FROM user_tables 
   WHERE table_name LIKE 'B1T%'

在早期版本中,您可以对必须首先编译的 PL/SQL 函数执行相同操作,如下所示:

CREATE OR REPLACE FUNCTION count_rows(t_name IN VARCHAR2) RETURN NUMBER  
AS  
  l_rows NUMBER;  
BEGIN  
  EXECUTE IMMEDIATE 'SELECT COUNT(*)  FROM ' || t_name INTO l_rows;  
  RETURN l_rows;  
END;  
/ 

编译它,然后在与上述相同的 SELECT 语句中使用它。

如果你只需要总计,你可以使用

SELECT SUM(row_count) FROM (SELECT .....)

其中子查询是第一个代码 sn-p 中显示的查询。

【讨论】:

以上是关于在一个查询中计算多个表的行数的主要内容,如果未能解决你的问题,请参考以下文章

7.04 求一个表的行数

计算带有子查询的行数的比率

计算基本事实表的行数

在 TSQL 中,如何添加一个计数列来计算查询中的行数?

HIVE/Impala 查询:计算满足特定条件的行之间的行数

计算laravel中查询返回的行数