使用Oracle SQL Developer编写查询未交易用户的SQL语句
嗨,我来帮你搞定这个查询未产生交易记录用户的需求~ 结合你提供的表结构,这里有几种在Oracle SQL里常用且高效的写法:
给定表结构与数据
users表
| u_id | country |
|---|---|
| 11 | Germany |
| 22 | Germany |
| 33 | Italy |
| 44 | France |
| 55 | Spain |
| 66 | Italy |
| 77 | Italy |
transactions表(已提供的部分数据)
| id | u_id | id_cat |
|---|---|---|
| A | 11 | 2 |
| B | 22 | 1 |
方法1:LEFT JOIN + IS NULL 筛选
这是最直观的写法,通过左连接保留所有用户,再过滤出没有匹配交易的记录:
SELECT u.u_id, u.country FROM users u LEFT JOIN transactions t ON u.u_id = t.u_id WHERE t.u_id IS NULL;
原理:LEFT JOIN会返回users表的所有行,即使transactions表中没有对应u_id的记录,此时t.u_id会是NULL,我们通过这个条件就能筛选出从未有过交易的用户。
方法2:NOT EXISTS 子查询
这种写法在Oracle中通常性能更优(尤其是当transactions.u_id有索引时),因为它会在找到第一个匹配记录后就停止检查:
SELECT u.u_id, u.country FROM users u WHERE NOT EXISTS ( SELECT 1 -- 这里用1比用*更高效,不需要返回实际列 FROM transactions t WHERE t.u_id = u.u_id );
原理:对于users中的每一行,子查询会检查transactions里是否存在相同u_id的记录,如果不存在,就保留该用户。
方法3:NOT IN 子查询(需注意NULL情况)
如果能确保transactions.u_id字段没有NULL值,也可以用这种写法:
SELECT u.u_id, u.country FROM users u WHERE u.u_id NOT IN ( SELECT DISTINCT t.u_id FROM transactions t );
注意:如果transactions里的u_id存在NULL,NOT IN会返回空结果,因为SQL中任何值和NULL比较都返回未知,所以这种情况下更推荐用前两种方法。加上DISTINCT是为了减少子查询返回的行数,提升查询效率。
内容的提问来源于stack exchange,提问作者riloth
相关产品推荐
相关产品推荐

