ChatGPT解决这个技术问题 Extra ChatGPT

是否可以在 Count() 中指定条件?

是否可以在 Count() 中指定条件?我只想计算位置列中具有例如“经理”的行。

我想在 count 语句中这样做,而不是使用 WHERE;我之所以问这个问题是因为我需要在同一个 SELECT 中同时计算 Managers 和 Other (类似于 Count(Position = Manager), Count(Position = Other)) 所以 WHERE 在这个例子中对我没有用处。

嘘所有 * 用户,使用 Count(SomeColumnInYourTable) where Position = 'Manager'
@Mark:在所有现代数据库上,这没有任何区别。
@Mark & Philippe:实际上它可以产生很大的不同。如果该字段可以为空且未建立索引,则查询需要触及表中的每条记录,因此使用 count(*) 和 count(field) 可以获得不同的结果和不同的性能。
多年来,我已经分析了 count(*) 与 count(x) 的执行计划,但到目前为止,我还没有找到一个表现出性能差异的执行计划。这就是为什么我真的很想看到一个存在差异的查询示例。
@Matthew:我们不是在谈论 SELECT *,而是在谈论 SELECT COUNT(*),这是一种完全不同的野兽。

G
Guffa

如果您不能仅使用 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 ...

如果我的字段是整数并且我想匹配 null 怎么办?以这种方式不起作用 select count(case IntegerField when 'NULL' then 1 else null end) from
@Faizan null 很特别。使用case when IntegerField is null then ...
使用布尔字段时,您可以使用:SUM(CONVERT(int, IsManager))
SQL Server 暗示 else null 用于 case 语句,因此 count() 示例可以短 10 个字符(如果计算空格)。
D
D'Arcy Rittich

假设您不想限制返回的行,因为您也在聚合其他值,您可以这样做:

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 ...

@RedFilter 甚至不需要指定 else 部分,只需 end1 之后。
@Denis:正确-我经常将 else 留在其中,因为它可以更好地记录 case 语句的结果,尤其是对于新手 SQL 开发人员。为简洁起见,在这种情况下可以将其删除。
H
Hivenfour

@Guffa 的答案非常好,只需指出使用 IF 语句可能更干净

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

我用了这个,但是,它应该是 IIF,而不是 IF。 :) database.guide/sql-server-if-vs-iif-whats-the-difference
@Brian MacKay,你是对的,我在考虑 mysql ^^¡,答案已编辑。
d
d219

取决于您的意思,但对含义的另一种解释是您想要计算具有特定值的行,但不想将 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

s
samjewell

如果使用 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


M
Matthew Whited

如果您使用 SQL 2005 或更高版本,也可以使用 Pivot 关键字

more info 和来自 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')

D
Dana

你的意思是这样的:

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

如果是这样,那么是的,那行得通!


编辑显示他不想使用 WHERE 子句限制行
z
z00l

我知道这真的很老了,但我喜欢这种情况下的 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

评论赞赏:-)


T
Thomas Decaux

注意 PrestoDB SQL(来自 Facebook),有一个快捷方式:

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

count_if(x) → bigint 返回 TRUE 输入值的数量。此函数等价于 count(CASE WHEN x THEN 1 END)


4
4b0

这是我为获得一个数据集所做的,该数据集包括每个集装箱内的总数和符合标准的数量。这让我回答了“有多少个集装箱有超过 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

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

不,问题明确表示“我想在 count 语句中执行此操作,而不是使用 WHERE”
N
NawaMan

我认为您可以使用一个简单的 WHERE 子句来仅选择一些记录。


为什么我会投反对票?在我回答之后(或者可能是同一时间),很多人回答了类似的事情,他们没有得到任何反对意见。 /:(
因为问题是“在 Count 中指定条件”而不是“按条件计算值”,所以您投了反对票。所以你在回答错误的问题
对答案投反对票有点不公平,当答案被写出来时,它是问题的正确解决方案......他在这个答案后 4 分钟添加了额外的文字!