SQL CASE WHEN去重问题:无法识别CASE生成列的IS NOT NULL筛选
解决行转列的重复行问题
这问题我太熟悉了!你现在碰到的是典型的**行转列(Pivoting)**场景,原来的CASE语句只是把对应标签的值填到对应列,但没把同一question_id的行合并起来,所以才会出现两行带NULL的结果;而且你想用WHERE过滤别名列的思路走不通,因为SQL的执行顺序是先跑WHERE,再生成SELECT里的别名,这时候别名还不存在呢!
给你两个靠谱的解决方案:
方案一:用聚合函数+GROUP BY(通用所有SQL数据库)
这是最兼容的写法,不管你用MySQL、PostgreSQL还是其他数据库都能用:
SELECT question_id, MAX(CASE WHEN tag = 'EN' THEN Question END) AS English, MAX(CASE WHEN tag = 'DE' THEN Question END) AS German FROM your_table_name -- 记得把这里换成你的真实表名 GROUP BY question_id;
原理很简单:MAX()函数会自动忽略NULL值,同一question_id下,EN对应的非NULL值会被保留,DE同理;GROUP BY question_id把相同ID的行合并成一行,正好得到你想要的结构。
方案二:用PIVOT语法(部分数据库支持)
如果你的数据库支持PIVOT(比如Oracle、SQL Server、PostgreSQL 11+),可以用更简洁的写法:
SELECT * FROM your_table_name PIVOT ( MAX(Question) FOR Tag IN ('EN' AS English, 'DE' AS German) ) AS pivoted_result;
这个语法更直观,直接指定要转的列和对应别名,底层逻辑和方案一其实是一致的。
另外再提一句:以后碰到想过滤SELECT别名列的情况,要么把CASE逻辑移到WHERE里(但这里不适用),要么用子查询/CTE先生成别名列再过滤,不过这次的问题核心是合并行,不是过滤,所以上面的方案就足够啦。
内容的提问来源于stack exchange,提问作者F.D
相关产品推荐
相关产品推荐

