【问题标题】:two SQL COUNT() queries?两个 SQL COUNT() 查询?
【发布时间】:2009-05-20 15:45:42
【问题描述】:

我想计算表中的总记录数和符合特定条件的总记录数。我可以通过两个单独的查询来完成这些:

SELECT COUNT(*) AS TotalCount FROM MyTable;
SELECT COUNT(*) AS QualifiedCount FROM MyTable
  {possible JOIN(s) as well e.g. JOIN MyOtherTable mot ON MyTable.id=mot.id} 
  WHERE {conditions};

有没有办法将这些组合成一个查询,以便我在一行中获得两个字段?

SELECT {something} AS TotalCount, 
  {something else} AS QualifiedCount 
  FROM MyTable {possible JOIN(s)} WHERE {some conditions}

如果没有,我可以发出两个查询并将它们包装在一个事务中,以便它们保持一致,但我希望用一个来完成。

edit:我最关心的是原子性;如果需要两个子 SELECT 语句,只要有来自某个地方的 INSERT 不会使两个响应不一致,就可以了。

编辑 2:CASE 答案很有帮助,但在我的具体情况下,条件可能包括与另一个表的 JOIN(忘记在我的原始帖子中提及,抱歉)所以我猜这种方法行不通。

【问题讨论】:

  • 你用的是什么数据库?
  • MySQL 但如果它非常简单,我想大致了解它
  • 与解决方案相关但与解决方案无关:您还可以使用它来获取较大表的计数。选择 SQL_CALC_FOUND_ROWSFROM 我的表;选择 FOUND_ROWS(); SELECT SQL_CALC_FOUND_ROWSFROM MyTable WHERE {条件}; SELECT FOUND_ROWS();

标签: sql


【解决方案1】:

一种方法是将表与自身连接起来:

select
   count(*) as TotalCount,
   count(s.id) as QualifiedCount
from
   MyTable a
left join
   MyTable s on s.id = a.id and {some conditions}

另一种方法是使用子查询:

select
   (select count(*) from Mytable) as TotalCount,
   (select count(*) from Mytable where {some conditions}) as QualifiedCount

或者您可以将条件放在一个案例中:

select
   count(*) as TotalCount,
   sum(case when {some conditions} then 1 else 0 end) as QualifiedCount
from
   MyTable

相关:

SQL Combining several SELECT results

【讨论】:

  • 自连接处理条件中有其他连接的情况。
【解决方案2】:

在 Sql Server 或 MySQL 中,您可以使用 CASE 语句来做到这一点:

select 
    count(*) as TotalCount,
    sum(case when {conditions} then 1 else 0 end) as QualifiedCount
from MyTable

编辑:如果您在条件中使用 JOIN,这也有效:

select 
    count(*) as TotalCount,
    sum(case when {conditions} then 1 else 0 end) as QualifiedCount
from MyTable t
left join MyChair c on c.TableId = t.Id
group by t.id, t.[othercolums]

GROUP BY 是为了确保您只能从主表中找到一行。

【讨论】:

  • 只想指出,这个例子的性能比任何联合或连接都要好,因为它只需要评估一次有问题的表
  • 我喜欢这种技术,它很优雅。
  • 语法“Alias = Expression”是 SqlServer/MySQL 特有的还是相当通用的?
  • 这是非常具体的 SqlServer,我会更改它
  • 我不会想到像这样使用 Sum()。 +1
【解决方案3】:

如果您只是计算行数,则可以使用嵌套查询。

select 
    (SELECT COUNT(*) AS TotalCount FROM MyTable) as a,
    (SELECT COUNT(*) AS QualifiedCount FROM MyTable WHERE {conditions}) as b

【讨论】:

  • 我同意这是获得您想要的结果的更好方法,并且应该在大约与单独执行相同的时间内将其提供给您。
  • 这个查询会给你答案,但是两个 select 语句和 where 子句的开销让 CASE 解决方案更高效
【解决方案4】:

在 Oracle SQL Developer 中,我必须在我的选择中添加 * FROM,否则会出现语法错误:

select * FROM 
    (select COUNT(*) as foo FROM TABLE1),
    (select COUNT(*) as boo FROM TABLE2);

【讨论】:

    【解决方案5】:

    MySQL 不计算 NULL,所以这也应该有效:

    SELECT count(*) AS TotalCount, 
      count( if( field = value, field, null)) AS QualifiedCount 
      FROM MyTable {possible JOIN(s)} WHERE {some conditions}
    

    如果 QuailifiedCount 字段来自 LEFT JOIN,则效果很好,并且您只关心它是否存在。获取用户数,以及填写地址的用户数:

    SELECT count( user.id) as NumUsers, count( address.id) as NumAddresses
      FROM Users
      LEFT JOIN Address on User.address_id = Address.id;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-22
      • 1970-01-01
      • 2021-04-22
      • 1970-01-01
      • 2012-12-26
      • 2011-12-11
      相关资源
      最近更新 更多