два запроса SQL COUNT ()? - PullRequest
9 голосов
/ 20 мая 2009

Я хочу посчитать как общее количество записей в таблице, так и общее количество записей, соответствующих определенным условиям. Я могу сделать это с двумя отдельными запросами:

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: меня больше всего волнует атомарность; если нужны два оператора sub-SELECT, то это нормально, если есть откуда-то INSERT, это не делает два ответа несовместимыми.

edit 2: ответы CASE полезны, но в моем конкретном случае условия могут включать в себя СОЕДИНЕНИЕ с другой таблицей (забыл упомянуть об этом в моем исходном сообщении, извините), поэтому я предполагаю, что этот подход не будет работать.

Ответы [ 4 ]

22 голосов
/ 20 мая 2009

Один из способов - присоединиться к столу против себя:

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, объединяющий несколько результатов SELECT

20 голосов
/ 20 мая 2009

В 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 предназначена для того, чтобы вы могли найти только одну строку из главной таблицы.

7 голосов
/ 20 мая 2009

если вы просто подсчитываете строки, вы можете просто использовать вложенные запросы.

select 
    (SELECT COUNT(*) AS TotalCount FROM MyTable) as a,
    (SELECT COUNT(*) AS QualifiedCount FROM MyTable WHERE {conditions}) as b
0 голосов
/ 20 мая 2009

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...