提问人:steve mcqueen 提问时间:11/5/2023 最后编辑:Dale Ksteve mcqueen 更新时间:11/6/2023 访问量:72
查看差异表
Make a view of a difference table
问:
让我们想象两个表 - T_Name、T_nameAttributes
T_name
名字 | 名称 ID |
---|---|
萨拉 | 2 |
马修 | 3 |
T_nameAttributes
名称 ID | 属性 ID | 价值 |
---|---|---|
2 | 3 | 红苹果 |
2 | 5 | 20美元 |
最初从它们中检索数据如下所示
select *
from T_name
left join T_nameAttributes
on T_name.NameID = T_nameAttributes.NameID
and AttributeID = 3 and nameID = 2
Sara, 3, Red Apple
每天,这些值都保存到相同的表架构中,并带有一个额外的“日期”列,在这里一切都很好,我可以轻松地检索请求日期的值
这里的问题 - 我想节省数据库空间并仅存储更改的值,所以我的日志表现在看起来像这样:(这部分已经完成)
T_NameLog
日期 | 名字 | 名称 ID |
---|---|---|
2023-01-01 | 萨拉 | 2 |
2023-10-05 | 莎拉 | 2 // 名称已更改 |
T_nameAttributesLog
日期 | 属性 ID | 名称 ID | 价值 |
---|---|---|---|
2023-01-01 | 3 | 2 | 红苹果 |
2023-10-04 | 3 | 2 | 青苹果 // 值已更改 |
2023-01-01 | 5 | 2 | 20美元 |
2023-02-12 | 5 | 2 | 0元 |
2023-10-09 | 5 | 2 | 70美元 |
问题:两个表都可以在随机日期更改其值,我想检索一个联接表,其中包含基于一个月中每天的行
Select date, name, value
from T_NameLog
left join T_nameAttributesLog <...>
where date between '2023-10-02' and '2023-10-05'
and AttributeID = 3 and nameID = 2
预期结果:
日期 | 名字 | 属性 |
---|---|---|
2023-10-02 | 萨拉 | 红苹果 |
2023-10-03 | 萨拉 | 红苹果 |
2023-10-04 | 萨拉 | 青苹果 |
2023-10-05 | 莎拉 | 青苹果 |
答:
0赞
Thorsten Kettner
11/5/2023
#1
首先为每个日期生成一行。然后与子句一起使用以获取表的最新行。我没有只查找一个名称和一个属性,而是编写了我的查询,以便它可以找到所有名称和属性。这是通过与 .CROSS APPLY
TOP
TOP (1) WITH TIES
ORDER BY RANK()
如果只想使用一个名称或仅使用一个属性,只需注释掉子句中的 ID 条件即可。(但在这种情况下,没有从句和仅 .WHERE
TOP (1)
WITH TIES
ORDER BY [Date] DESC
with
days as
(
select cast('2023-10-02' as date) as dt,
cast('2023-10-05' as date) as last_dt
union all
select dateadd(day, 1, dt),
last_dt
from days
where dt < last_dt
)
select days.dt, n.name, na.value
from days
cross apply
(
select top (1) with ties
nl.name,
nl.nameid
from t_namelog nl
where nl.[Date] <= days.dt
-- and nl.nameid = 2
order by rank() over (partition by nl.nameid order by nl.[Date] desc)
) n
cross apply
(
select top (1) with ties
nal.value,
nal.attributeid
from t_nameattributeslog nal
where nal.nameid = n.nameid
and nal.[Date] <= days.dt
-- and nal.attributeid = 3
order by rank() over (partition by nal.attributeid order by nal.[Date] desc)
) na
order by days.dt, n.nameid, na.attributeid;
演示:https://dbfiddle.uk/WyhGYzqy
评论
0赞
steve mcqueen
11/5/2023
非常感谢!我会试试的
评论