PostgreSQL:追加合并列结构不同的两张表
这种跨数据源的时间序列合并需求太普遍了,不管是做数据分析还是数据清洗,几乎都会碰到。我给你整理了几种主流工具的实战解决方案,都是我平时常用的:
Python Pandas 解决方案
Pandas是处理这类数据最灵活的工具,完全能覆盖你的需求:
加载并对齐列
先把两个数据集读进来,直接用pd.concat纵向堆叠,它会自动对齐列名,不存在的列自动填充NaN:import pandas as pd # 加载数据 df1 = pd.read_csv("数据源1.csv") df2 = pd.read_csv("数据源2.csv") # 纵向堆叠,自动对齐列,重置索引 combined_df = pd.concat([df1, df2], axis=0, ignore_index=True)处理重叠行
时间序列的重叠行可以根据时间列去重,你可以选择保留最新的(比如数据源2的)或者最早的(数据源1的):# 假设时间列名为"timestamp" # keep='last'保留最后出现的行,适合优先用新数据源的数据;keep='first'则相反 combined_df = combined_df.drop_duplicates(subset="timestamp", keep="last")额外优化:统一列名
如果两个表的同一含义列名不同(比如一个叫"销售额",一个叫"sales"),先重命名再合并:df2.rename(columns={"sales": "销售额", "record_time": "timestamp"}, inplace=True)
Excel/Power Query 解决方案
如果你习惯用Excel,Power Query可视化操作就能搞定,不用写代码:
导入数据到Power Query
分别把两个表导入Power Query(菜单栏「数据」>「获取数据」>「从表格/区域」),每个表会生成一个独立的查询。追加合并表
在Power Query编辑器里,选中其中一个查询,点击「主页」>「追加查询」>「追加两个表」,选择另一个表。Power Query会自动匹配列名,缺失的列会填充null。删除重叠行
选中时间列,点击「主页」>「删除重复项」,默认保留第一行;如果要保留最后一行,可以先按时间列降序排序,再删除重复项。列名统一
如果列名不匹配,在查询里右键列名重命名,确保同一含义的列名完全一致后再追加。
SQL 解决方案
如果数据存在数据库里,用SQL直接合并更高效:
PostgreSQL 示例
用UNION ALL堆叠所有行,再用DISTINCT ON按时间列去重,控制保留哪个数据源的行:
WITH combined_data AS ( -- 给每个数据源加标识,方便控制优先级 SELECT *, 'source1' AS data_source FROM table1 UNION ALL SELECT *, 'source2' AS data_source FROM table2 ) -- 按时间列分组,保留data_source排序靠后的行(这里source2优先级更高) SELECT DISTINCT ON (timestamp) * FROM combined_data ORDER BY timestamp, data_source DESC;
MySQL 示例
MySQL没有DISTINCT ON,用窗口函数实现同样效果:
WITH combined_data AS ( SELECT *, 'source1' AS data_source FROM table1 UNION ALL SELECT *, 'source2' AS data_source FROM table2 ), ranked_data AS ( -- 按时间列分组,给每行排名,source2排第一 SELECT *, ROW_NUMBER() OVER (PARTITION BY timestamp ORDER BY data_source DESC) AS rn FROM combined_data ) -- 只保留每组的第一行 SELECT col1, col2, col3, timestamp FROM ranked_data WHERE rn = 1;
关键注意事项
- 统一时间格式:这是最容易踩坑的点!一定要确保两个表的时间列是相同的格式(比如都是
YYYY-MM-DD HH:MM:SS的datetime类型),否则去重会失效。 - 列映射检查:合并前仔细核对列的含义,避免把不同含义的列强行对齐。
- 缺失值后续处理:合并后的缺失值可以根据业务需求填充,比如时间序列常用前向填充(Pandas里的
ffill())或者按均值填充。
内容的提问来源于stack exchange,提问作者eternity1

