赞
踩
拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。
比如下面的表:
user_id | name | level | start_time | end_time |
---|---|---|---|---|
1 | 甲 | A | 2020-05-01 | 9999-12-31 |
2 | 乙 | B | 2020-05-01 | 2020-05-02 |
2 | 乙 | A | 2020-05-02 | 9999-12-31 |
3 | 丙 | B | 2020-05-02 | 9999-12-31 |
上面就是一个简单的拉链表,记录了每个用户随着时间的变化其等级的变动情况。
在数据仓库的数据模型设计过程中,经常会遇到下面这种表的设计:
链接
:https://www.jianshu.com/p/799252156379
CREATE TABLE IF NOT EXISTS link_first(
user_id BIGINT
,name STRING
,level STRING
,time STRING
)
COMMENT "link_first";
insert into link_first
values (1,'甲','A','2020-05-01'),
(2,'乙','B','2020-05-01');
SELECT * from link_first
数据如下
user_id | name | level | time |
---|---|---|---|
1 | 甲 | A | 2020-05-01 |
2 | 乙 | B | 2020-05-01 |
CREATE TABLE IF NOT EXISTS link_second(
user_id BIGINT
,name STRING
,level STRING
,time STRING
)
COMMENT "link_second";
insert into link_second
values (1,'甲','A','2020-05-02'),
(2,'乙','A','2020-05-02'),
(3,'丙','B','2020-05-02');
SELECT * from link_second
数据如下
user_id | name | level | time |
---|---|---|---|
1 | 甲 | A | 2020-05-02 |
2 | 乙 | A | 2020-05-02 |
3 | 丙 | B | 2020-05-02 |
CREATE TABLE IF NOT EXISTS level_his(
user_id BIGINT
,name STRING
,level STRING
,start_time STRING
,end_time STRING
)
COMMENT "level_his";
INSERT OVERWRITE TABLE level_his
SELECT *
FROM (
SELECT DISTINCT(user_id),name,level,'2020-05-01' as start_time,'9999-12-31' as end_time
FROM link_first
--WHERE id !=''
)t
SELECT * from level_his;
数据如下
user_id | name | level | start_time | end_time |
---|---|---|---|---|
1 | 甲 | A | 2020-05-01 | 9999-12-31 |
2 | 乙 | B | 2020-05-01 | 9999-12-31 |
CREATE TABLE IF NOT EXISTS level_update(
user_id BIGINT
,name STRING
,level STRING
,time STRING
)
COMMENT 'level_update'
;
INSERT OVERWRITE TABLE level_update
SELECT *
FROM (
SELECT a.*
FROM
(SELECT DISTINCT(user_id),name,level,time FROM link_second )a
LEFT OUTER JOIN
(SELECT DISTINCT(user_id),name,level,time FROM link_first )b ON
a.user_id = b.user_id
WHERE a.level!=b.level
OR b.level IS NULL
)t;
SELECT * from level_update;
数据如下
user_id | name | level | time |
---|---|---|---|
3 | 丙 | B | 2020-05-02 |
2 | 乙 | A | 2020-05-02 |
INSERT OVERWRITE TABLE level_his
SELECT *
FROM
(
SELECT a.user_id
, a.name
, a.level
, a.start_time
,(CASE
WHEN a.end_time='9999-12-31' AND b.user_id IS NOT NULL THEN '2020-05-02' --在变动表中出现的,需要把时间改为5月2日(如果是实时表,就是最新时间)
ELSE a.end_time
END) AS end_time
FROM level_his a
LEFT JOIN level_update b ON a.user_id = b.user_id
UNION
SELECT c.user_id
,c.name
,c.level
,'2020-05-02' as start_time
,'9999-12-31' as end_time --变动表里面的数据需要把start_time改成5月2日(如果是实时表,就是最新时间);end_time改成'9999-12-31'
FROM level_update c
)t;
SELECT * from level_his ORDER BY user_id;
就可以得到最终的结果了
如下:
就可以得到我们文章开头提到的表格了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。