Можно ли указать условие в Count()?

Можно ли указать условие в Count()? Я хотел бы посчитать только те строки, которые имеют, например, "Менеджер" в столбце "Позиция".

Я хочу сделать это в операторе подсчета, не используя WHERE; Я спрашиваю об этом, потому что мне нужно посчитать и менеджеров, и других в одном и том же SELECT (что-то вроде Count(Position = Manager), Count(Position = Other)) поэтому в данном примере WHERE для меня бесполезно.

Ответ 1

Если вы не можете просто ограничить сам запрос предложением where, вы можете использовать тот факт, что агрегат count учитывает только ненулевые значения:

select count(case Position when 'Manager' then 1 else null end)
from ...

Вы также можете использовать агрегат sum аналогичным образом:

select sum(case Position when 'Manager' then 1 else 0 end)
from ...

Ответ 2

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

select count(case when Position = 'Manager' then 1 else null end) as ManagerCount
from ...

Скажем, в том же столбце у вас были значения Manager, Supervisor и Team Lead, вы могли бы подсчитать количество таких, как это:

select count(case when Position = 'Manager' then 1 else null end) as ManagerCount,
    count(case when Position = 'Supervisor' then 1 else null end) as SupervisorCount,
    count(case when Position = 'Team Lead' then 1 else null end) as TeamLeadCount,
from ...

Ответ 3

@Ответ Guffa превосходный, просто укажите, что, возможно, он чище с инструкцией IF

select count(IF(Position = 'Manager', 1, NULL)) as ManagerCount
from ...

Ответ 4

Зависит от того, что вы имеете в виду, но другая интерпретация значения - это то, где вы хотите посчитать строки с определенным значением, но не хотите ограничивать SELECT ТОЛЬКО этими строками...

Вы бы сделали это с помощью SUM() с предложением, например, вместо использования COUNT(): например

SELECT SUM(CASE WHEN Position = 'Manager' THEN 1 ELSE 0 END) AS ManagerCount,
    SUM(CASE WHEN Position = 'CEO' THEN 1 ELSE 0 END) AS CEOCount
FROM SomeTable

Ответ 5

Вы также можете использовать Pivot Keyword, если вы используете SQL 2005 или выше

дополнительная информация и Technet

SELECT *
FROM @Users
PIVOT (
    COUNT(Position)
    FOR Position
    IN (Manager, CEO, Employee)
) as p

Набор тестовых данных

DECLARE @Users TABLE (Position VARCHAR(10))
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('CEO')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')

Ответ 6

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

NULLIF может оказать небольшое отрицательное влияние на производительность, но я думаю, что он все равно будет быстрее, чем подзапросы.

DECLARE @tbl TABLE ( id [int] NOT NULL, field [varchar](50) NOT NULL)

INSERT INTO @tbl (id, field)
SELECT 1, 'Manager'
UNION SELECT 2, 'Manager'
UNION SELECT 3, 'Customer'
UNION SELECT 4, 'Boss'
UNION SELECT 5, 'Intern'
UNION SELECT 6, 'Customer'
UNION SELECT 7, 'Customer'
UNION SELECT 8, 'Wife'
UNION SELECT 9, 'Son'

SELECT * FROM @tbl

SELECT 
    COUNT(1) AS [total]
    ,COUNT(1) - COUNT(NULLIF([field], 'Manager')) AS [Managers]
    ,COUNT(NULLIF([field], 'Manager')) AS [NotManagers]
    ,(COUNT(1) - COUNT(NULLIF([field], 'Wife'))) + (COUNT(1) - COUNT(NULLIF([field], 'Son'))) AS [Family]
FROM @tbl

Комментарии оценены: -)

Ответ 7

Вы имеете в виду только это:

SELECT Count(*) FROM YourTable WHERE Position = 'Manager'

Если да, то работает yup!

Ответ 8

SELECT COUNT(*) FROM bla WHERE Position = 'Manager'

Ответ 9

Я думаю, вы можете использовать простое предложение WHERE, чтобы выбрать только подсчет некоторой записи.

Ответ 10

Обратите внимание, что в PrestoDB SQL (из Facebook) есть ярлык:

https://prestodb.io/docs/current/functions/aggregate.html

count_if (x) → bigint

Возвращает количество ИСТИННЫХ входных значений. Эта функция эквивалентна счету (СЛУЧАЙ, КОГДА x ТОГДА 1 КОНЕЦ)

Ответ 11

Вот что я сделал, чтобы получить набор данных, который включал в себя как общее количество, так и число, отвечающее критериям, в каждом транспортном контейнере. Это позволило мне ответить на вопрос: "Сколько судоходных контейнеров имеют более чем X% товаров по размеру 51"

select
   Schedule,
   PackageNum,
   COUNT (UniqueID) as Total,
   SUM (
   case
      when
         Size > 51 
      then
         1 
      else
         0 
   end
) as NumOverSize 
from
   Inventory 
where
   customer like '%PEPSI%' 
group by
   Schedule, PackageNum

Ответ 12

Просто добавьте предложение WHERE, и вы хорошо пойдете.

Ответ 13

С помощью этого вы получите счет для менеджеров

Select Position, count(*) as 'Position Counter'
from your_table 
group by Position