You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL中能否用ANY结合OVER(PARTITION BY)实现分区内条件判断?

如何判断每行所属公司是否存在Tom?

针对你的问题先直接给结论:你写的any(people = 'Tom') over (partition by company order by company)语句在大多数SQL数据库里无法运行——因为ANY通常是用于子查询的比较运算符(比如WHERE col = ANY(...)),并不支持作为窗口聚合函数使用。不过我们有几种更合适的方法来实现你的需求:

方法1:用布尔聚合函数直接实现(部分数据库支持)

如果你的数据库支持布尔聚合函数(比如PostgreSQL),可以直接用BOOL_OR来判断分区内是否存在符合条件的行,写法更简洁:

select *, 
       bool_or(people = 'Tom') over (partition by company) as find_tom 
from t1;

这个语句会直接返回每个公司分区内是否存在Tom(true表示存在,false表示不存在)。

方法2:你的两步替代方案(通用所有数据库)

你给出的两步方案逻辑清晰,完全可以实现需求,而且适配所有主流SQL数据库。我们再梳理并优化一下:

  1. 第一步:给每行标记是否为Tom,生成中间表t2
-- step 1: 生成是否为Tom的二进制标记
select *,
       case when people = 'Tom' then 1 else 0 end as has_tom 
into t2 
from t1;
  1. 第二步:用窗口函数MAX()统计每个公司的标记最大值,判断是否存在Tom
-- 统计每个公司是否存在Tom
select *, 
       case when max(has_tom) over (partition by company) = 1 then 'has tom' else 'no tom' end as find_tom 
from t2;

这里可以去掉order by company,因为已经按company分区,排序不会影响MAX()的结果,语句更简洁。

执行后会得到你预期的结果:

companypeoplehas_tomfind_tom
appleJessi0has tom
appleTom1has tom
fbAlex0no tom
fbNick0no tom

方法3:合并成单语句(无需中间表)

如果不想创建中间表,可以把两步逻辑合并成一个语句,避免额外的表操作:

select *,
       case when max(case when people = 'Tom' then 1 else 0 end) over (partition by company) = 1 
            then 'has tom' 
            else 'no tom' 
       end as find_tom
from t1;

这个语句和你的两步方案逻辑完全一致,但更高效。

内容的提问来源于stack exchange,提问作者YJZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:08:30