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

LEFT JOIN子查询仅返回单个患病用户问题排查求助

问题分析:LEFT JOIN仅返回一名患病用户的原因及修复方案

问题描述

我有一份员工列表,通过LEFT JOIN users_ill表判断用户是否患病。现在遇到的问题是:数据库里有多名health_at字段为NULL的患病用户,但查询结果只显示一名;调整排序规则后,显示的患病用户会变,但始终只能显示一名。请问我的SQL语句哪里错了?

Users Ill表结构

id | int
user_id | uuid
health_at | timestamp null
created_at | timestamp

原SQL代码

SELECT 
 u.id as user_id, u.firstname, u.lastname, u.created_at,
 ui.created_at as ill_since
 FROM users u

 LEFT JOIN (
   SELECT user_id, created_at FROM users_ill WHERE health_at IS NULL ORDER BY created_at DESC 
   LIMIT 1
 ) ui ON (ui.user_id = u.id)

WHERE u.tenant_id = $1 AND u.deleted_by IS NULL
ORDER BY u.firstname ASC LIMIT 50 OFFSET $8;

问题根源

你的子查询里加了LIMIT 1,这个限制会让子查询只返回单条符合条件的记录——也就是所有health_at IS NULL的记录里,created_at最晚的那一条。之后LEFT JOIN只会把这条记录的user_id和用户表匹配,所以最终只有这一个用户能显示ill_since,其他用户的该字段都是NULL。调整排序规则时,子查询返回的单条记录会变,所以显示的患病用户也跟着变,但始终只会有一个。

修复方案

根据你的需求,有两种修复方式:

需求1:给每个用户显示最新的一条患病记录(health_at IS NULL)

去掉子查询的LIMIT 1,改成按user_id分组,取每个用户最新的患病记录时间:

SELECT 
 u.id as user_id, u.firstname, u.lastname, u.created_at,
 ui.ill_since
 FROM users u

 LEFT JOIN (
   SELECT user_id, MAX(created_at) as ill_since 
   FROM users_ill 
   WHERE health_at IS NULL 
   GROUP BY user_id
 ) ui ON (ui.user_id = u.id)

WHERE u.tenant_id = $1 AND u.deleted_by IS NULL
ORDER BY u.firstname ASC LIMIT 50 OFFSET $8;

需求2:显示用户所有的患病记录(注意会产生多行)

如果需要展示用户的每一条符合条件的患病记录,直接关联整个过滤后的users_ill表即可:

SELECT 
 u.id as user_id, u.firstname, u.lastname, u.created_at,
 ui.created_at as ill_since
 FROM users u

 LEFT JOIN users_ill ui ON ui.user_id = u.id AND ui.health_at IS NULL

WHERE u.tenant_id = $1 AND u.deleted_by IS NULL
ORDER BY u.firstname ASC LIMIT 50 OFFSET $8;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:06:14