是否可以在 Count()
中指定条件?我只想计算位置列中具有例如“经理”的行。
我想在 count 语句中这样做,而不是使用 WHERE
;我之所以问这个问题是因为我需要在同一个 SELECT
中同时计算 Managers 和 Other (类似于 Count(Position = Manager), Count(Position = Other))
所以 WHERE
在这个例子中对我没有用处。
SELECT *
,而是在谈论 SELECT COUNT(*)
,这是一种完全不同的野兽。
如果您不能仅使用 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 ...
假设您不想限制返回的行,因为您也在聚合其他值,您可以这样做:
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 ...
else
部分,只需 end
在 1
之后。
else
留在其中,因为它可以更好地记录 case 语句的结果,尤其是对于新手 SQL 开发人员。为简洁起见,在这种情况下可以将其删除。
@Guffa 的答案非常好,只需指出使用 IF 语句可能更干净
select count(IIF(Position = 'Manager', 1, NULL)) as ManagerCount
from ...
取决于您的意思,但对含义的另一种解释是您想要计算具有特定值的行,但不想将 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
如果使用 Postgres 或 SQLite,您可以使用 Filter 子句来提高可读性:
SELECT
COUNT(1) FILTER (WHERE POSITION = 'Manager') AS ManagerCount,
COUNT(1) FILTER (WHERE POSITION = 'Other') AS OtherCount
FROM ...
BigQuery 还具有 Countif
- 在此处查看不同 SQL 方言对这些功能的支持:https://modern-sql.com/feature/filter
如果您使用 SQL 2005 或更高版本,也可以使用 Pivot 关键字
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')
你的意思是这样的:
SELECT Count(*) FROM YourTable WHERE Position = 'Manager'
如果是这样,那么是的,那行得通!
我知道这真的很老了,但我喜欢这种情况下的 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
评论赞赏:-)
注意 PrestoDB SQL(来自 Facebook),有一个快捷方式:
https://prestodb.io/docs/current/functions/aggregate.html
count_if(x) → bigint 返回 TRUE 输入值的数量。此函数等价于 count(CASE WHEN x THEN 1 END)
这是我为获得一个数据集所做的,该数据集包括每个集装箱内的总数和符合标准的数量。这让我回答了“有多少个集装箱有超过 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
SELECT COUNT(*) FROM bla WHERE Position = 'Manager'
我认为您可以使用一个简单的 WHERE 子句来仅选择一些记录。
不定期副业成功案例分享
null
很特别。使用case when IntegerField is null then ...
SUM(CONVERT(int, IsManager))
else null
用于case
语句,因此count()
示例可以短 10 个字符(如果计算空格)。