以下查询用于计算单个查询中两个不相关表中的行数。
With t1 as (Select 1
Union Select 2
Union Select 3),
t2 as (Select 'A'
Union Select 'B')
Select (Select count(*) from t1), (Select count(*) from t2)
是否有更好的方法可以避免选择查询中的两个select语句。
输出应为
3 2
任何特定于Postgres的构造也会这样做。
答案 0 :(得分:3)
首先,您可以使用VALUES
表达式而不是更详细的UNION ALL SELECT
来简化测试用例。
如果数据类型不是默认的integer
和text
,那么您需要在第一行显式类型转换。
其次,FULL OUTER JOIN
完全没有意义。它所做的就是让你的查询更慢。如果任何行在另一个表中有多个匹配,则它会在计数中相乘。
WITH t1(col1, col2) AS (VALUES (1, 1), (2, 2), (3, 3))
,t2(col1, col2) AS (VALUES (1, 'A'), (2, 'B'), (2, 'C')) -- 2nd row for "2"
SELECT count(t1.*), count(t2.*)
FROM t1
FULL OUTER JOIN t2 USING (col1);
收率:
4 3
错误。
WITH t1(col2) AS (VALUES (1), (2), ( 3))
,t2(col2) AS (VALUES ('A'), ('B'), ('C'))
SELECT (SELECT count(*) FROM t1) AS t1_ct
,(SELECT count(*) FROM t1) AS t2_ct;
收率:
3 3
正确,除了更简单,更快
不可否认,新申请row_number()
,就不会有愚蠢行为。但这只是浪费时间。
大桌子的计数相对较慢。如果您不需要完全计数但可以使用估算值,那么您可以非常快速地实现这一目标:
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE oid = 'myschema.mytable'::regclass;
我引用the manual here:
它由VACUUM,ANALYZE和一些DDL命令更新,例如 创建指数。
答案 1 :(得分:0)
计数是一项非常昂贵的操作(就CPU负载而言)。尽可能避免。如果您需要在没有任何条件的情况下获取表的总行数,则某些RDBMS会提供一种解决方法,例如:使用MSSQL,它是这样的:
select SUM(row_count) as Total_Rows
from sys.dm_db_partition_stats
where object_name(object_id) = 'YourTableName'
and index_id < 2
另一种方法是将您的点数保存在单独的表格中,例如如果您需要按特定值分组的总数。您可以使用触发器增加和减少计数。如果您(例如)必须始终在主表单上显示计数(活动用户,每个区域的活动帖子等),则建议使用此方法。
答案 2 :(得分:-2)
通过添加row_number列并执行完全外部联接来介绍两个表之间的关系。
With t1 as (Select 1 as Col1, 1
Union Select 2, 2
Union Select 3, 3),
t2 as (Select -1 as Col1, 'A'
Union Select -2, 'B')
Select count(t1.*), count(t2.*) from t1 full outer join t2 on t1.Col1 = t2.Col1