Два запроса SQL COUNT()?
Я хочу подсчитать как общее количество записей в таблице, так и общее количество записей, соответствующих определенным условиям. Я могу сделать это с двумя отдельными запросами:
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}
Если нет, я могу выполнить два запроса и обернуть их в транзакцию, чтобы они были согласованы, но я надеялся сделать это с одним.
редактировать: меня больше всего волнует атомарность; если есть два оператора sub-SELECT, то это нормально, если есть INSERT, идущий откуда-то, это не делает два ответа несовместимыми.
правка 2: ответы CASE полезны, но в моем конкретном случае условия могут включать в себя СОЕДИНЕНИЕ с другой таблицей (забыл упомянуть об этом в моем исходном сообщении, извините), поэтому я предполагаю, что этот подход не будет работать.
4 ответа
Один из способов - присоединиться к столу против себя:
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 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 предназначена для того, чтобы вы могли найти только одну строку из основной таблицы.
Если вы просто считаете строки, вы можете просто использовать вложенные запросы.
select
(SELECT COUNT(*) AS TotalCount FROM MyTable) as a,
(SELECT COUNT(*) AS QualifiedCount FROM MyTable WHERE {conditions}) as b
В Oracle SQL Developer мне пришлось добавить * FROM в моем выборе, иначе я получал синтаксическую ошибку:
select * FROM
(select COUNT(*) as foo FROM TABLE1),
(select COUNT(*) as boo FROM TABLE2);
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;