最近遇到了刷数据的场景,每天产出的原始数据大概有4亿条,4亿条数据刷到在线服务中,平均qps也有5k左右了,意义不是很大,考虑到数据也不是每天都在变,于是产生了查diff的需求。
MINUS
在搜索引擎上一搜,很容易就看到了可以用MINUS
实现
SELECT * FROM T1
MINUS
SELECT * FROM T2
可惜无论 MySQL 还是 Hive 都不支持。
Left Join
Left Join 保证了左表的数据一定会存在,对于这类查Diff的场景很合适
下面这个语句可以查出来 T2中比T1新增的列
key代表表示唯一信息的那一列,例如用户ID之类
SELECT * FOROM T1
LEFT JOIN
SELECT * FROM T2
ON T1.key = T2.key
WHERE
T2.key is NULL
如果还想关注 某一列的指标是否变化,可以在where后添加筛选条件
SELECT * FOROM T1
LEFT JOIN
SELECT * FROM T2
ON T1.key = T2.key
WHERE
T2.key is NULL OR T1.data_key != T2.data_key
对于hive中,是同一张表不同分区,要在left join之前,先把对应两个分区的数据查出来
(SELECT * FROM TableName where datetime=20200201) T1
LEFT JOIN
(SELECT * FROM TableName where datetime=20200202) T2
ON T1.key = T2.key
WHERE
T2.key is NULL OR T1.data_key != T2.data_key
UNION ALL
UNION 命令只会选取不同的值,UNION ALL 会包括全部的值
SELECT col1, col2, col3
FROM
(
SELECT * FROM tableA
UNION ALL
SELECT * FROM tableB
) data
GROUP BY col1, col2, col3
HAVING count(*)!=2
NOT EXISTS
效率比较低 就不说了
参考资料
quick-best-way-compare-two-tables-sql
sql-set-operator-minus-alternative-in-hive-and-examples
sql-compare-data-from-two-tables
minus-operator-giving-me-erros-in-mysql