基于值列表创建SQL新列:二进制标识生成问题求助
问题解决方案
1. 先搞定type全为0的问题
你之前的SQL大概率是没处理好逗号分隔字符串的边界匹配——比如直接用Indicator LIKE '%a%'会误匹配ca这种包含a但不是独立标识的情况,或者a在开头/结尾时没覆盖到。
正确的做法是给字符串前后补逗号,再匹配带逗号的目标值,确保匹配的是独立标识:
SELECT *, CASE WHEN ',' + Indicator + ',' LIKE '%,[ab],%' THEN 1 ELSE 0 END AS type INTO NewTable FROM OriginalTable;
这里[ab]是简化写法,等价于同时匹配%,a,%和%,b,%,如果需要更明确也可以写成OR连接的两个条件。
2. 高效处理200+标识值的方法
写200多个CASE分支显然不现实,用匹配值表关联的方式更高效:
第一步:建个匹配值表(临时表或永久表都行)
-- 临时表示例,也可以用表变量 CREATE TABLE #MatchValues (Value VARCHAR(50)); INSERT INTO #MatchValues VALUES ('a'), ('b'), ('c'), ...; -- 把所有需要匹配的200+标识插进去
第二步:根据数据库类型选对应的关联逻辑
不同数据库的字符串拆分函数不一样,下面是常用的几种:
MySQL/MariaDB
SELECT o.*, CASE WHEN EXISTS ( SELECT 1 FROM #MatchValues m WHERE FIND_IN_SET(m.Value, o.Indicator) > 0 ) THEN 1 ELSE 0 END AS type INTO NewTable FROM OriginalTable o;
SQL Server
SELECT o.*, CASE WHEN EXISTS ( SELECT 1 FROM #MatchValues m JOIN STRING_SPLIT(o.Indicator, ',') s ON s.value = m.Value ) THEN 1 ELSE 0 END AS type INTO NewTable FROM OriginalTable o;
PostgreSQL
SELECT o.*, CASE WHEN EXISTS ( SELECT 1 FROM #MatchValues m JOIN UNNEST(string_to_array(o.Indicator, ',')) s ON s = m.Value ) THEN 1 ELSE 0 END AS type INTO NewTable FROM OriginalTable o;
这种方式的优势:
- 新增/修改匹配值只需要维护
#MatchValues表,不用改查询逻辑 - 性能比一堆OR的CASE语句好,数据量大时更明显
- 逻辑清晰,后期维护成本低
兼容老版本数据库的写法
如果你的数据库不支持内置拆分函数,用LIKE关联也能实现:
SELECT o.*, CASE WHEN EXISTS ( SELECT 1 FROM #MatchValues m WHERE ',' + o.Indicator + ',' LIKE '%,' + m.Value + ',%' ) THEN 1 ELSE 0 END AS type INTO NewTable FROM OriginalTable o;
这种写法几乎兼容所有SQL数据库,不需要依赖特定函数。
内容的提问来源于stack exchange,提问作者code_for_your_life
相关产品推荐
相关产品推荐

