PostgreSQL中如何将单ID行的多日期与字符串拆分为多行
解决方案:将指定ID的多组日期-字符串拆分为单行记录
嘿,这个需求其实就是把宽表转换为窄表(行转列的反向操作,也叫「unpivot」),针对指定ID处理的话,不同数据库有不同的实现方式,我给你整理了几种主流数据库的方案:
1. MySQL 实现
MySQL没有原生的unpivot函数,我们可以用UNION ALL来拼接每组日期和字符串的查询结果:
SELECT Date1 AS `Date`, String1 AS `String` FROM your_table_name WHERE ID = 'INI111' AND Date1 IS NOT NULL -- 可选:过滤空日期的行 UNION ALL SELECT Date2 AS `Date`, String2 AS `String` FROM your_table_name WHERE ID = 'INI111' AND Date2 IS NOT NULL UNION ALL SELECT Date3 AS `Date`, String3 AS `String` FROM your_table_name WHERE ID = 'INI111' AND Date3 IS NOT NULL;
如果后续有更多组(比如Date4/String4),只需要新增一段UNION ALL的查询即可。
2. SQL Server 实现
SQL Server推荐用CROSS APPLY + VALUES的组合,可读性和维护性都更高:
SELECT v.[Date], v.[String] FROM your_table_name t CROSS APPLY ( VALUES (t.Date1, t.String1), (t.Date2, t.String2), (t.Date3, t.String3) ) v([Date], [String]) WHERE t.ID = 'INI111' AND v.[Date] IS NOT NULL; -- 可选:过滤空值行
3. PostgreSQL 实现
PostgreSQL可以用LATERAL JOIN + VALUES的方式,逻辑直观易懂:
SELECT dt_str.date_val AS "Date", dt_str.string_val AS "String" FROM your_table_name t LATERAL ( VALUES (t.Date1, t.String1), (t.Date2, t.String2), (t.Date3, t.String3) ) AS dt_str(date_val, string_val) WHERE t.ID = 'INI111' AND dt_str.date_val IS NOT NULL;
注意事项
- 记得把代码里的
your_table_name替换成你实际使用的表名 - 如果不需要过滤空值行,可以去掉
AND xxx IS NOT NULL的条件 - 如果有更多组日期/字符串,只需要在
VALUES里新增对应的行即可
内容的提问来源于stack exchange,提问作者Imrik
相关产品推荐
相关产品推荐

