You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Sybase(T-SQL)一对多关联查询:筛选所有关联保险记录date_resolved为NULL的案件号

搞定Sybase(T-SQL)里的这个筛选难题:只取所有关联保险记录date_resolved全为NULL的案件号

先理清楚问题和场景

咱们有两张表:cases存案件基本信息,insurance存每个案件对应的多条保险记录,结构如下:

  • cases表:仅包含casenum(案件号)字段
  • insurance表:包含ins_iddate_resolved(结案日期)、case_num(关联案件号)字段

需求很明确:只返回那些所有关联保险记录的date_resolved都是NULL的案件号。但之前写的查询都跑偏了——比如某个案件有3条保险记录,2条NULL、1条有值,结果也被查出来了,这显然不符合要求。

为啥之前的语句不对?

先拆解下你试过的两个语句的问题:

  1. 左连接子查询的写法:

    select casenum from cases left join (select date_resolved from insurance where date_resolved is null) ins on ins.case_num = cases.casenum
    

    这个语句只把insurancedate_resolved为NULL的记录挑出来和案件关联,只要案件有一条这样的记录就会被选中,完全没排查这个案件是不是还有其他非NULL的保险记录。

  2. 内连接加where条件的写法:

    select casenum from cases inner join insurance on cases.casenum = insurance.case_num where insurance.date_resolved is null
    

    这个逻辑更直接:找出所有存在至少一条date_resolved为NULL的保险记录的案件,但同样没过滤掉那些同时有非NULL记录的案件。

正确的解法来了!

核心思路是:先对每个案件的保险记录分组,用聚合函数判断该案件的所有date_resolved是否全为NULL。这里用max(date_resolved)非常合适——因为NULL在聚合函数中会被忽略,如果所有记录都是NULL,max()的结果就是NULL;只要有一条记录的date_resolved有值,max()就会返回那个非NULL的值,这样就能通过having子句把这类不符合要求的案件排除掉。

最终可用的T-SQL语句(你可以根据实际需求添加cases表的其他字段和筛选条件):

select casenum, -- 这里可以添加cases表的其他字段
       *other stuff* 
from cases 
inner join (
    select i.case_num 
    from insurance i 
    group by i.case_num 
    having max(date_resolved) is null
) ins on ins.case_num = cases.casenum 
where *other stuff from cases table* 
  and *more stuff from cases table*

额外补充

如果你的业务需求需要包含没有任何关联保险记录的案件(也就是该案件在insurance表中无对应记录),可以把inner join改成left join,并在where子句中添加ins.case_num is null的条件,具体可根据实际场景调整。

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

火山引擎 最新活动