如何在Snowflake中对比同表内同一ID的两行所有列?
问题:Snowflake员工新旧数据列对比自动化实现
我在Snowflake中有一张员工信息表,每个员工有唯一ID,每个ID对应两行数据:一行是最新/当前个人信息,另一行是旧系统的历史信息。表内有约70列(头衔、姓名、出生日期、地址、邮编、邮箱等),员工数量庞大。
需求:对比每个员工两行数据的所有列,输出单行结果——ID作为主键保留,其余列若两行值相同则显示0,不同则显示1。
示例
原表(MyTable)
| ID | FIRSTNAME | Salary |
|---|---|---|
| 123 | Jack | 20000 |
| 123 | Jack | 25000 |
输出结果
| ID | FIRSTNAME | Salary |
|---|---|---|
| 123 | 0 | 1 |
现有手动方案
我目前的实现需要手动逐个输入列名,代码如下:
SELECT CURRENT.ID , CASE WHEN CURRENT.FIRSTNAME = PREVIOUS.FIRSTNAME THEN FALSE ELSE TRUE END AS FIRSTNAME -- 其余所有列都要重复上述CASE逻辑 FROM MYTABLE CURRENT INNER JOIN MYTABLE PREVIOUS ON (CURRENT.ID = PREVIOUS.ID) WHERE CURRENT.VERSION = 'CURRENT' AND PREVIOUS.VERSION = 'PREVIOUS'
但我知道肯定有更高效的方法,如果SQL实现太复杂,用Python处理也可以。
优化方案
方案1:利用Snowflake元数据自动生成SQL
通过查询Snowflake的信息模式(INFORMATION_SCHEMA)获取表的列名,自动拼接CASE语句,避免手动编写70次重复逻辑:
SELECT STRING_AGG( CONCAT( ', CASE WHEN CURRENT.', COLUMN_NAME, ' = PREVIOUS.', COLUMN_NAME, ' THEN 0 ELSE 1 END AS ', COLUMN_NAME ), '\n' ) AS COLUMN_CASE_STATEMENTS FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '你的模式名' AND TABLE_NAME = 'MYTABLE' AND COLUMN_NAME NOT IN ('ID', 'VERSION');
执行这段SQL后,会得到所有列的CASE语句片段,直接复制到你的基础SQL中即可。
方案2:Python处理(Pandas实现)
如果SQL自动生成觉得麻烦,用Python读取数据后对比更直观:
import snowflake.connector import pandas as pd # 连接Snowflake conn = snowflake.connector.connect( user='你的用户名', password='你的密码', account='你的账户名', warehouse='你的仓库', database='你的数据库', schema='你的模式' ) # 读取全表数据 query = "SELECT * FROM MYTABLE;" df = pd.read_sql(query, conn) # 拆分当前和历史数据,按ID索引 current_df = df[df['VERSION'] == 'CURRENT'].set_index('ID') previous_df = df[df['VERSION'] == 'PREVIOUS'].set_index('ID') # 逐列对比,相同为0,不同为1 result_df = (current_df != previous_df).astype(int).reset_index() # 输出结果或写回Snowflake print(result_df) # result_df.to_sql('EMPLOYEE_COMPARISON_RESULT', conn, if_exists='replace', index=False) conn.close()
内容的提问来源于stack exchange,提问作者BShardz
相关产品推荐
相关产品推荐

