我有一个包含 ID、值和日期的表。此表中有许多 ID、值和日期。
记录会定期插入到该表中。ID 将始终保持不变,但偶尔值会更改。
我如何编写一个查询,它会给我 ID 加上值更改的最近时间?注意:该值将始终增加。
从这个样本数据:
Create Table Taco
( Taco_ID int,
Taco_value int,
Taco_date datetime)
Insert INTO Taco
Values (1, 1, '2012-07-01 00:00:01'),
(1, 1, '2012-07-01 00:00:02'),
(1, 1, '2012-07-01 00:00:03'),
(1, 1, '2012-07-01 00:00:04'),
(1, 2, '2012-07-01 00:00:05'),
(1, 2, '2012-07-01 00:00:06'),
(1, 2, '2012-07-01 00:00:07'),
(1, 2, '2012-07-01 00:00:08')
结果应该是:
Taco_ID Taco_date
1 2012-07-01 00:00:05
(因为 00:05 是最后一次Taco_Value
更改。)
Taco_value
这两个查询依赖于始终随时间增加的假设。具有较少窗口函数疯狂的替代方案:
SQLfiddle上的示例
更新
对于那些跟踪的人来说,如果
Taco_value
可以重复会发生什么,则存在争议。如果它可以从 1 变为 2,然后对于任何给定的 1Taco_ID
,则查询将不起作用。这是针对这种情况的解决方案,即使它不是像 Itzik Ben-Gan 这样的人可能能够梦想的间隙和岛屿技术,即使它与 OP 的场景无关 - 它可能是与未来的读者相关。它有点复杂,我还添加了一个额外的变量 - aTaco_ID
只有一个Taco_value
.如果要包含任何 ID 的第一行,其中值在整个集合中根本没有改变:
如果你想排除这些行,它会更复杂一些,但仍然是微小的变化:
更新了 SQLfiddle 示例
基本上,这是@Taryn 的建议“浓缩”为没有派生表的单个 SELECT:
注意:此解决方案考虑了
Taco_value
只能增加的规定。(更准确地说,它假设Taco_value
不能变回以前的值——实际上与链接的答案相同。)查询的 SQL Fiddle 演示:http ://sqlfiddle.com/#!3/91368/2
您应该能够同时使用
min()
和max()
聚合函数得到结果:请参阅带有演示的 SQL Fiddle
另一个答案是基于这些值不会重新出现的假设(这基本上是@Aaron 的查询 2,浓缩在一个更少的嵌套中):
测试:SQL-Fiddle
以及一个更普遍的问题的答案,其中值可以重新出现:
(或使用
CROSS APPLY
所有相关行,包括value
,显示):测试:SQL-Fiddle-2
仅供参考 +1 用于提供样本结构和数据。我唯一可以要求的是该数据的预期输出。
编辑:这个会让我发疯。我只是新手,有一种“简单”的方法可以做到这一点。我摆脱了不正确的解决方案,并提出了一个我认为是正确的解决方案。这是一个类似于@bluefeets 的解决方案,但它涵盖了@AaronBertrand 提供的测试。
为什么不直接获取滞后值和超前值的差值?如果差异为零,它没有改变,它不是零,然后它改变了。这可以通过一个简单的查询来完成:
今天有一个类似的问题 - 在 Power BI 中,我可以使用 Tabler.FillDown 解决它。经过一番搜索,我找到了 FillDown 的 SQL 变体:
https://www.oraylis.de/blog/fill-down-table-in-t-sql-last-non-empty-value
因此,我花时间将该解决方案调整到此示例 - 添加了一个额外的行以显示 Taco_value 的重用。
注意:此解决方案考虑到 Taco_value 可以增加和减少(或变回以前的值)
结果:
这可以像下面这样简单吗?
鉴于 taco_value 总是增加?
ps我自己是SQL初学者,但是学习缓慢但肯定。