0

我试图在不编写函数的情况下解决查询中的问题。我有一个表,其中包含如下用户信息:

user_id user_name user_phone_number user_location created_at
1         abc          123              X         2014-01-01
1         abc          123              X         2014-02-01
1         abc          123              Y         2014-10-01
1         abc          123              Z         2014-11-01
1         abc          123              Z         2014-12-01
1         abc          123              X         2015-01-01

我需要将其制作为 SCD-Type II 表,如下所示:

user_id user_name user_ph_num user_location valid_from_dt valid_to_dt   
1         abc        123         X           2014-01-01   2014-09-30
1         abc        123         Y           2014-10-01   2014-10-31
1         abc        123         Z           2014-11-01   2014-12-31
1         abc        123         X           2015-01-01   2999-12-31

我认为实现这一点的是:

一步:temp_table1:

id user_name user_ph_num user_location created_at is_same_with_previous
1         abc     123              X   2014-01-01          f
1         abc     123              X   2014-02-01          t
1         abc     123              Y   2014-10-01          f
1         abc     123              Z   2014-11-01          f
1         abc     123              Z   2014-12-01          t
1         abc     123              X   2015-01-01          f

第二步:

临时表2:

id user_name user_ph_num user_loc created_at is_same_with_previous sr_no
1         abc     123        X    2014-01-01          f             1
1         abc     123        X    2014-02-01          t             1
1         abc     123        Y    2014-10-01          f             2
1         abc     123        Z    2014-11-01          f             3
1         abc     123        Z    2014-12-01          t             3
1         abc     123        X    2015-01-01          f             4

在此之后,我可以如下查询并获得所需的结果:

select id,user_name,user_ph_num,user_loc,min(created_at) as valid_from,
max(created_at) as valid_to
from temp_table2
group by sr_no,id,user_name,user_ph_num,user_loc;

我创建了第 1 步,但未能创建 temp_table2(第 2 步)。我正在使用以下查询来完成此操作:

select setval('ser_no',2);

select *
CASE WHEN is_same_with_previous 
THEN (SELECT setval('ser_no',nextval('ser_no')-1))
ELSE nextval('ser_no') END as diff_sr_no
from temp_table1;

结果为:temp_table2:

id user_name user_ph_num user_loc created_at is_same_with_previous sr_no
1         abc     123        X    2014-01-01          f             1
1         abc     123        X    2014-02-01          t             1
1         abc     123        Y    2014-10-01          f             2
1         abc     123        Z    2014-11-01          f             3
1         abc     123        Z    2014-12-01          t             1
1         abc     123        X    2015-01-01          f             4

有人可以帮助解决这个问题吗?我使用正确的方法吗?提前致谢!!!

4

1 回答 1

0

您使用了错误的方法。你应该看看数据库中的“窗口函数”,你可能需要“row_number()”、“rank()”和“lag()”。通常可以在单个查询中完成创建 SCD2。在您的情况下,查询应该:

  1. 删除所有字段上的重复项
  2. 将 rank() 应用于除“created_at”之外的所有字段的分区并按“created_at”排序
  3. 对于每个等级,选择最小值“created_at”
  4. “created_at”是 valid_from,“lag(created_at) over partition by (order by created_at desc)”作为 valid_to
于 2015-08-06T08:43:31.637 回答