如何判断搜索字符串是否存在于多列?SQL语句疑问及大小写需求
首先明确你的核心需求:找出FirstTable(A表)中,someCol的值既没有出现在SecondTable(B表)的column1里,也没有出现在column2里的所有记录,同时要求查询大小写不敏感。
咱们先拆解你现有语句的问题:
1. JOIN类型导致漏数据
你用的是INNER JOIN,这会过滤掉A表中那些ID在B表里没有匹配项的记录——但这些记录其实完全符合你的需求(因为B表里根本没有对应数据,自然someCol不会出现在B的任何列里),所以这部分数据会被无辜漏掉。
2. 未处理大小写不敏感
你的语句里没有做大小写统一处理,不同数据库的LIKE默认行为不同(比如SQL Server默认区分大小写,MySQL如果是_ci排序规则才不区分),所以会出现大小写不一致时匹配失败的情况。
3. 逻辑判断的等价性
你提到把NOT放在LIKE旁也无效,其实你的原语句逻辑(NOT B.column1 LIKE ...) AND (NOT B.column2 LIKE ...),和需求对应的逻辑NOT (B.column1 LIKE ... OR B.column2 LIKE ...)是完全等价的(德摩根定律),这部分逻辑本身是没问题的。
修正后的SQL语句
针对上面的问题,我们可以调整为LEFT JOIN来保留A表所有记录,同时通过统一大小写实现不敏感查询。这里给出通用版本(适配多数数据库):
SELECT A.* -- 建议替换成你实际需要的字段,避免不必要的性能开销 FROM [FirstTable] AS A LEFT JOIN [SecondTable] AS B ON A.ID = B.ID WHERE -- 两种符合条件的情况: -- 1. B表中没有匹配A的ID,直接符合需求 B.ID IS NULL OR -- 2. B表有匹配,但column1和column2都不包含A.someCol(统一转小写实现大小写不敏感) (NOT LOWER(B.column1) LIKE '%' + LOWER(A.someCol) + '%' AND NOT LOWER(B.column2) LIKE '%' + LOWER(A.someCol) + '%')
如果你的数据库有更简洁的大小写不敏感语法,可以替换:
- PostgreSQL:用
ILIKE代替LIKE,不用转小写:NOT B.column1 ILIKE '%' || A.someCol || '%' - SQL Server:也可以用
COLLATE指定不区分大小写的排序规则,比如B.column1 LIKE '%' + A.someCol + '%' COLLATE SQL_Latin1_General_CP1_CI_AS
额外注意点
如果A.someCol可能为NULL,需要额外处理——因为NULL和任何值做LIKE比较都会返回UNKNOWN,导致这部分记录被过滤。可以在WHERE里加上AND A.someCol IS NOT NULL,或者根据你的需求决定是否保留someCol为NULL的记录。
内容的提问来源于stack exchange,提问作者AnthonyFG

