如何筛选任意列均不含Not、NO值的表行 无需逐列编写where条件
解决方案
核心思路是利用数据库的JSON序列化能力或者系统元数据批量判断所有列的值,完全避免手动逐列编写过滤条件,适配列数极多的场景。
方案1:JSON函数快速实现(无需写列名,适配绝大多数主流数据库)
MySQL 5.7+/8.0 写法
直接将整行序列化为JSON,搜索是否存在目标值即可:
SELECT * FROM 你的表名 WHERE JSON_SEARCH(JSON_OBJECT(*), 'one', 'Not') IS NULL AND JSON_SEARCH(JSON_OBJECT(*), 'one', 'NO') IS NULL;
如果需要匹配大小写不敏感的场景(比如能匹配not/NOT/No等),修改为:
SELECT * FROM 你的表名 WHERE JSON_SEARCH(LOWER(JSON_OBJECT(*)), 'one', 'not') IS NULL AND JSON_SEARCH(LOWER(JSON_OBJECT(*)), 'one', 'no') IS NULL;
PostgreSQL 写法
SELECT * FROM 你的表名 t WHERE NOT EXISTS ( SELECT 1 FROM json_each_text(row_to_json(t.*)) WHERE value IN ('Not', 'NO') );
SQL Server 写法
SELECT * FROM 你的表名 t WHERE NOT EXISTS ( SELECT 1 FROM OPENJSON((SELECT t.* FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)) WHERE value IN ('Not', 'NO') );
方案2:动态生成SQL(兼容所有数据库,性能更优)
如果数据库不支持JSON函数,或者需要更高的查询性能,可以通过系统元数据表自动拼接出所有列的过滤条件,无需手动逐列编写:
MySQL 示例
- 先执行元数据查询生成目标SQL:
SELECT CONCAT( 'SELECT * FROM 你的表名 WHERE ', GROUP_CONCAT( CONCAT('`', COLUMN_NAME, '` NOT IN (''Not'', ''NO'')') SEPARATOR ' AND ' ) ) AS 生成的查询语句 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '你的数据库名' AND TABLE_NAME = '你的表名' -- 如果有非字符串类型的列,可以加这个过滤只判断字符串列,避免类型报错 AND DATA_TYPE IN ('varchar', 'char', 'text');
- 复制上一步输出的
生成的查询语句直接执行即可得到结果。
注意事项
- 如果表中存在非字符串类型的列,建议在动态生成SQL时只筛选字符串类型的列做判断,避免JSON序列化或者类型转换带来的异常
- 数据量极大的场景优先选择动态生成SQL的方案,执行性能远高于JSON函数方案
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

