如何更新视图中指定列的重复值,使其全部变为唯一值
解决方案
注意:视图本身是基于基表生成的虚拟表,无法直接对视图数据执行UPDATE操作,你可以选择调整视图定义生成带唯一值c3的结果,或者直接修改基表的原始数据,两种方案的实现逻辑如下:
方案1:调整视图定义,直接生成符合要求的唯一c3列
用窗口函数ROW_NUMBER()给相同c3值的行做序号标记,再拼接字符串即可,主流数据库(MySQL 8.0+/PostgreSQL/SQL Server/Oracle)都支持该语法:
CREATE OR REPLACE VIEW your_view_name AS SELECT c1, c2, CASE WHEN COUNT(*) OVER (PARTITION BY c3) = 1 THEN c3 ELSE CONCAT( TRIM(SUBSTRING_INDEX(c3, '-', 1)), ROW_NUMBER() OVER (PARTITION BY c3 ORDER BY c1), ' - ', TRIM(SUBSTRING_INDEX(c3, '-', -1)) ) END AS c3 FROM your_base_table;
逻辑说明:先统计每个c3值的出现次数,仅出现1次的保留原值,出现多次的拆分短横线前后的内容,拼上对应序号后再组装回原格式,ORDER BY后的字段可以根据你自己的排序需求替换成c2或者其他列。
方案2:直接修改基表的c3字段值
如果你需要持久化修改原始数据,可以用以下逻辑实现(以MySQL为例,其他数据库语法仅字符串拼接、拆分函数有差异,逻辑通用):
UPDATE your_base_table t1 JOIN ( SELECT c1, c2, c3, ROW_NUMBER() OVER (PARTITION BY c3 ORDER BY c1) AS rn, COUNT(*) OVER (PARTITION BY c3) AS cnt FROM your_base_table ) t2 ON t1.c1 = t2.c1 AND t1.c2 = t2.c2 AND t1.c3 = t2.c3 SET t1.c3 = CASE WHEN t2.cnt = 1 THEN t1.c3 ELSE CONCAT(TRIM(SUBSTRING_INDEX(t1.c3, '-', 1)), t2.rn, ' - ', TRIM(SUBSTRING_INDEX(t1.c3, '-', -1))) END;
注意:执行前建议先把SET部分替换成SELECT语句验证修改结果是否符合预期,避免误改数据。
内容的提问来源于stack exchange,提问作者JJ13596
相关产品推荐
相关产品推荐

