赛题来源2023年全国职业院校技能大赛赛题第1套任务B中数据清洗模块
子任务二:数据清洗
编写Scala代码,使用Spark将ods库中相应表数据全量抽取到Hive的dwd库中对应表中。表中有涉及到timestamp类型的,均要求按照yyyy-MM-dd HH:mm:ss,不记录毫秒数,若原数据中只有年月日,则在时分秒的位置添加00:00:00,添加之后使其符合yyyy-MM-dd HH:mm:ss。
第一题
抽取ods库中user_info表中昨天的分区(子任务一生成的分区)数据,并结合dim_user_info最新分区现有的数据,根据id合并数据到dwd库中dim_user_info的分区表(合并是指对dwd层数据进行插入或修改,需修改的数据以id为合并字段,根据operate_time排序取最新的一条),分区字段为etl_date且值与ods库的相对应表该值相等,同时若operate_time为空,则用create_time填充,并添加dwd_insert_user、dwd_insert_time、dwd_modify_user、dwd_modify_time四列,其中dwd_insert_user、dwd_modify_user均填写“user1”。若该条记录第一次进入数仓dwd层则dwd_insert_time、dwd_modify_time均存当前操作时间,并进行数据类型转换。若该数据在进入dwd层时发生了合并修改,则dwd_insert_time时间不变,dwd_modify_time存当前操作时间,其余列存最新的值。使用hive cli执行show partitions dwd.dim_user_info命令,将结果截图粘贴至客户端桌面【Release\任务B提交结果.docx】中对应的任务序号下
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
object DWD01 {
def main(args: Array[String]): Unit = {
System.setProperty("HADOOP_USER_NAME", "atguigu")
// TODO 创建Spark连接
val conf = new SparkConf().setMaster("local[*]").setAppName("DWD01")
val spark = SparkSession.builder().config(conf).enableHiveSupport().getOrCreate()
spark.conf.set("hive.exec.dynamic.partition.mode", "nonstrict")
spark.sparkContext.setLogLevel("OFF")
// TODO 执行核心SQL
val result = spark.sql(
"""
|select
| new.id,
| new.login_name,
| new.nick_name,
| new.passwd,
| new.name,
| new.phone_num,
| new.email,
| new.head_img,
| new.user_level,
| new.birthday,
| new.gender,
| new.create_time,
| `if`(nvl(new.operate_time), new.create_time, new.operate_time) as `operate_time`,
| new.status,
| 'user1' dwd_insert_user,
| `if`(nvl(new.operate_time),
| new.operate_time,
| date_format(`current_date`(), 'yyyy-MM-dd HH:mm:ss')) dwd_insert_time,
| 'user1' dwd_modify_user,
| date_format(`current_date`(), 'yyyy-MM-dd HH:mm:ss') dwd_modify_time,
| new.etldate
|from (
| select
| id,
| login_name,
| nick_name,
| passwd,
| name,
| phone_num,
| email,
| head_img,
| user_level,
| birthday,
| gender,
| create_time,
| operate_time,
| status,
| etldate
| from ods.user_info
| where etldate = '20240101'
|) new
|left join (
| select
| id,
| login_name,
| nick_name,
| passwd,
| name,
| phone_num,
| email,
| head_img,
| user_level,
| birthday,
| gender,
| create_time,
| operate_time,
| status,
| etldate
| from dwd.user_info
| where etldate = (
| select -- 这里使用直接在查询条件中使用子查询返回单个值
| max(etldate) max_time