将1个日期范围映射到另一个日期范围的逻辑?

时间:2019-04-12 22:22:04

标签: datetime language-agnostic type-2-dimension

我有一张用户历史记录表,带有开始和结束日期。我还有第二个角色历史记录表,其中包含开始日期和结束日期。

我正在尝试获取用户历史记录表并将其与角色历史记录分开。基本上,我正在尝试将角色历史记录映射到用户历史记录。

例如:

这是用户表

<form method="post" action="">
Enter booking Id<input type="text" id='bookid' name='bookid' required>
<button class="button1" id="bcancel" name="bcancel" value="cancel">Cancel 
Booking</button>
</form>
<%
set conn=Server.CreateObject("ADODB.Connection")    
conn.Provider="Microsoft.Jet.OLEDB.4.0"    
conn.Open(Server.Mappath("Aurangabad1.mdb"))
set rs = Server.CreateObject("ADODB.recordset")

dim am,del
del="cancel"
am=request("bcancel")
if(am=del) then
sql="delete from booking where bid= '"& Request.form("bookid") & "'"
on error resume next
conn.Execute sql,info
if err<>0 then
Response.Write("<center>Booking Not Canceled..!</center>")
else
Response.Write("<center><h2>" & info & " Booking Canceled</h2></center>")
end if
end if
conn.close
%>

和角色历史记录表

| person | title       | roleid | start     | end         |
|--------|-------------|--------|-----------|-------------|
| a      | VP          | 1      | 10/1/2017 | 10/31/2017  |
| a      | Director    | NULL   | 11/1/2017 | 11/25/2017  |
| a      | NULL        | 2      | 11/26/2017| 12/5/2017   |
| a      | President   | 3      | 12/6/2017 | 12/31/2017  |
| a      | Exec        | 3      | 01/01/2018| 12/31/2999  |

我正在尝试获得这种结果:


| roleid | role        | xxxxxx | start      | end         |
|--------|-------------|--------|------------|-------------|
| 1      | Champion    | x      | 10/05/2017 | 11/01/2017  |
| 2      | Nerd        | x      | 10/20/2017 | 12/31/2999  |
| 3      | Peon        | x      | 11/26/2017 | 12/15/2017  |
| 3      | King        | x      | 12/16/207  | 12/31/2017  |

我尝试使用多个insert语句来解决这个问题,但是我一直在弄错逻辑。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

第一: 我通过如下的row_number函数在“用户表”中创建虚拟主键。

select *,ROW_NUMBER() OVER(order by person ,start) as vkey from 'user table'

使用上表,我将其假装为“临时表”,以便按vkey来获取必须加入“角色历史表”的行:

    select vkey,rn 
from(select * ,ROW_NUMBER() OVER (PARTITION BY person,roleid 
order by start) as rn) from 'temptable')temp where rn<=1

获得vkey之后,我们可以加入“角色历史记录表”以获得所需的结果。(我在表上方假装为“ keytable”):

    select t1.person,t1.title,t1.role_id,t2.role,t1.start,t1.end from 'temptable' t1 
left join 'role history table' t2 on t1.role_id=t2.role_id 
and t1.vkey in (select vkey from 'keytable') order by t1.vkey

答案 1 :(得分:0)

我找到了对我有帮助的答案。

“这里有两个Type2缓慢变化的尺寸(SCD)。通常,当您查询这种类型的数据时,您将使用单个时间点来分割数据。但是重叠吗?

这似乎很难做到,但是当您只考虑两个表并且了解一些逻辑时,该模式实际上还不错。

首先是testing overlapping ranges。认真地,将此答案添加为书签。太神奇了,我已经回头好几年了!

您将在两个表的连接上应用该答案的简化表达式:A.Start <= B.End AND A.End> B.Start

这将得到笛卡尔结果-很好。每行的真实有效范围是两个表中最小的重叠窗口:

,以A.开始> B.开始然后A.开始ELSE B.开始结束为例     AS New_Start ,当A.End

这应该给您一个新的,非规范化的Type2 SCD结果集。

如果您需要执行两个以上的表...好吧...我只是将两个表逐步连接在一起的脚本,将上一次连接的结果转发到下一个表中,采用与上述相同的模式。

希望这就是您想要的!”