虚构一个场景,具体说明一下Oracle、Spark SQL 在使用上的一些不同之处
比如有两个系统A、B 都存储了用户的信息,使用身份证号作为主键,并且有年龄、性别等信息,因为不同系统收集用户信息的方式不同,所以同一个人在不同系统的信息可能不同,比如在系统A 某个人的性别是男,但是在系统B 某个人的性别是女,现在需要编写SQL 筛选出这种不一致的数据
使用Oracle 写SQL 核对数据
left join 结合where
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
WHERE a.user_nbr = b.user_nbr AND a.gender != b.gender;
直接报错:SQL 错误 [905] [42000]: ORA-00905: 缺失关键字
在Oracle 中使用left join 应该结合on
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
ON a.user_nbr = b.user_nbr
WHERE a.gender != b.gender;
这个SQL 可以按照预期核对出来身份证号相同、性别不同的交易!
有可能系统A 有一个字段直接存储的身份证信息,系统B 则是存储的证件类型+身份证,身份证的证件类型是”01”,所以希望编写这样的SQL
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
ON '01'+a.user_nbr = b.user_nbr
WHERE a.gender != b.gender;
执行的时候,直接报错,报错信息为:SQL 错误 [1722] [42000]: ORA-01722: 无效数字
不能加则减,使用SUBSTR() 函数可以实现这个功能
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
ON a.user_nbr = SUBSTR(b.user_nbr, 3, 18)
WHERE a.gender != b.gender;
可以按照预期正确核对出来结果!
Spark SQL 进行测试
left join + where 的方式
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
WHERE a.user_nbr = b.user_nbr AND a.gender != b.gender;
Oracle 里面这种语法会报错!但是SparkSQL 中可以按照预期核对出来结果!
再试一下left join 结合on 编写SQL
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
ON a.user_nbr = b.user_nbr
WHERE a.gender != b.gender;
和上面核对出来的结果一致!
同样对比Oracle,有可能系统A 有一个字段直接存储的身份证信息,系统B 则是存储的证件类型+身份证,身份证的证件类型是”01”,所以希望编写这样的SQL
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
ON '01'+a.user_nbr = b.user_nbr
WHERE a.gender != b.gender;
没有报错,但是没有按照预期核对出来不一致的记录!
不能加则减,使用SUBSTR() 函数可以实现这个功能
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
ON a.user_nbr = SUBSTR(b.user_nbr, 3, 18)
WHERE a.gender != b.gender;
和Oracle 一致,这个SQL 在Spark SQL 中也可以得到预期的结果
既然有字符串截取函数,就还有字符串拼接函数CONCAT()
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
on CONCAT("01", a.user_nbr) = b.user_nbr
where a.gender != b.gender
也可以按照预期核对出来结果
还存在这样的情况,比如系统A 使用1、2 表示男、女;系统B 使用m、f 表示男、女,那这种情况如何编写SQL?
SELECT a.user_nbr, a.gender, b.gender
FROM tableA a LEFT JOIN tableB b
on CONCAT("01", a.user_nbr) = b.user_nbr
where (a.gender = '1' and b.gender!='m') or (a.gender='2' and b.gender!='f')
深入理解SQL
但就一个left join 而言,Oracle 与Spark SQL 就存在这么大的区别
所以在使用上有很多细节还是要慢慢总结的!!
另外,Flink SQL 呢?MySQL 呢?