0

以下查询用于计算单个查询中两个不相关表中的行数。

  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)

有没有更好的方法来避免选择查询中的两个选择语句。

输出应该是

3 2

任何特定于 Postgres 的构造也可以。

4

3 回答 3

3

简单正确

首先,您可以使用表达式VALUES而不是更冗长的UNION ALL SELECT.
如果数据类型不是默认数据类型,integer并且text..

其次,aFULL 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;

我在这里引用手册

它由 VACUUM、ANALYZE 和一些 DDL 命令(如 CREATE INDEX)更新。

此相关答案中的更多详细信息。

于 2012-12-31T11:51:52.900 回答
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

另一种方法是在单独的表中维护您的计数,例如,如果您需要按某个值分组的总数。您将使用触发器增加和减少计数。如果您(例如)必须一直在主窗体上显示计数(活跃用户、每个区域的活跃帖子等),建议您这样做。

于 2012-12-31T11:31:50.173 回答
-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
于 2012-12-31T10:07:57.510 回答