Oracle中如何编写SQL实现用户列表返回指定值或null?
需求描述
我有一个user表:
| USER_ID | FIRSTNAME | LASTNAME |
|---|---|---|
| 1000 | Tom | Doe |
| 2000 | Tina | Doe |
| 3000 | Michael | Doe |
| 4000 | Robert | Doe |
还有一个存储values的表(注:values是SQL关键字,需用反引号/方括号包裹避免语法错误):
| USER_ID | VALUE |
|---|---|
| 1000 | 10 |
| 2000 | 20 |
| 3000 | 40 |
| 4000 | 20 |
| 1000 | 20 |
| 3000 | 10 |
| 4000 | 30 |
需要编写SQL语句列出所有用户:当用户在values表中有值为10的记录时返回10,若值不为10或无对应记录则返回null,期望结果如下:
| USER_ID | FIRSTNAME | LASTNAME | VALUE |
|---|---|---|---|
| 1000 | Tom | Doe | 10 |
| 2000 | Tina | Doe | null |
| 3000 | Michael | Doe | 10 |
| 4000 | Robert | Doe | null |
解决方案
这里提供两种高效的实现方式:
方法一:左连接+条件聚合
通过LEFT JOIN关联两张表,结合MAX函数筛选出符合条件的VALUE(只要存在一条VALUE=10的记录就返回10,否则返回null):
SELECT u.USER_ID, u.FIRSTNAME, u.LASTNAME, MAX(CASE WHEN v.VALUE = 10 THEN 10 ELSE NULL END) AS VALUE FROM user u LEFT JOIN `values` v ON u.USER_ID = v.USER_ID GROUP BY u.USER_ID, u.FIRSTNAME, u.LASTNAME;
方法二:子查询+CASE表达式
用EXISTS子查询直接判断用户是否存在VALUE=10的记录,再通过CASE返回对应结果:
SELECT u.USER_ID, u.FIRSTNAME, u.LASTNAME, CASE WHEN EXISTS (SELECT 1 FROM `values` v WHERE v.USER_ID = u.USER_ID AND v.VALUE = 10) THEN 10 ELSE NULL END AS VALUE FROM user u;
说明
- 方法一适合需要同时处理其他聚合逻辑的场景,分组确保每个用户仅返回一行;
- 方法二更直观,在USER_ID字段有索引的情况下性能更优;
- 不同数据库对关键字的转义方式不同:MySQL用反引号`,SQL Server用方括号[],Oracle用双引号"",根据实际数据库调整即可。
内容的提问来源于stack exchange,提问作者user17634846
相关产品推荐
相关产品推荐

