如何查询ips表中blocked=1且无关联acc表记录的IP地址?
嘿,这个需求其实有几种靠谱的实现方式,我给你拆解一下,帮你补全SQL语句:
方法1:LEFT JOIN + IS NULL(直观易读)
这是最常用的写法之一,通过左连接关联两张表,筛选出关联表中无匹配的记录:
SELECT ips.ip FROM ips LEFT JOIN acc ON ips.ip = acc.ip WHERE ips.blocked = 1 AND acc.ip IS NULL;
原理很简单:LEFT JOIN会保留ips表中所有blocked=1的IP,哪怕acc表中没有对应的记录。如果acc表中找不到匹配的IP,acc.ip就会是NULL,我们只要把这些记录筛选出来就行。
方法2:NOT EXISTS子查询(逻辑更清晰)
这种写法的语义更贴近需求本身——“找出被封禁且不存在访问记录的IP”,很多数据库对这种写法的查询优化做得很好:
SELECT ip FROM ips WHERE blocked = 1 AND NOT EXISTS ( SELECT 1 FROM acc WHERE acc.ip = ips.ip );
这里的子查询会检查当前ips表的IP是否在acc表中有对应记录,如果没有,NOT EXISTS就会返回true,这条IP就会被纳入结果集。
方法3:NOT IN(需注意边界情况)
这种写法也能实现需求,但要小心:如果acc表的ip字段存在NULL值,NOT IN会直接返回空结果,所以只有在确定acc.ip不会为NULL的时候才推荐使用:
SELECT ip FROM ips WHERE blocked = 1 AND ip NOT IN (SELECT ip FROM acc);
它的逻辑是先从acc表取出所有已存在的IP列表,再筛选出ips表中被封禁且不在这个列表里的IP。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

