SQL Server在给定跟踪信息的一段时间内获取数据对象的基础位置
我不知道如何在SQLServer2008R2中得出这样的结论 我有一个表,它有一些输入,这些输入有一个父标记和一个时间戳 有时,这些对象的父标记在时间戳中发生了更改。此父标记可以随时更改。 假设我有下表。我当前的表有数百万个具有不同objectid的数据。查看该表,很容易看出ParentID在时间戳3到4、6到7和8到9中发生了更改 我想要的答案是ObjectID属于哪个ParentID以及开始和结束时间戳,时间戳timestamp=TS之间的增量值是多少 到目前为止,我所完成的是在发生变化时得到的,但它只给了我变化,而不是上表 下面是生成表和测试插入的代码。下面是获取更改的选择SQL Server在给定跟踪信息的一段时间内获取数据对象的基础位置,sql,sql-server,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008 R2,我不知道如何在SQLServer2008R2中得出这样的结论 我有一个表,它有一些输入,这些输入有一个父标记和一个时间戳 有时,这些对象的父标记在时间戳中发生了更改。此父标记可以随时更改。 假设我有下表。我当前的表有数百万个具有不同objectid的数据。查看该表,很容易看出ParentID在时间戳3到4、6到7和8到9中发生了更改 我想要的答案是ObjectID属于哪个ParentID以及开始和结束时间戳,时间戳timestamp=TS之间的增量值是多少 到目前为止,我所完成的是在发生变化时得
--Initial Insert Code
IF OBJECT_ID('tempdb..#Trackings') Is Not Null
Drop table #Trackings
Create Table #Trackings
(
ProductID bigint
, value float
, StoreID int
, DateID int
, Aux_Row_Number int
)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,1,325.2,1)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,2,326.2,2)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,3,329.6,3)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,4,335.2,4)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,5,336.5,5)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,6,338.3,6)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,7,339.2,7)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,8,342.1,8)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,9,343.7,9)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,10,355.0,10)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,12,385.0,12)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,13,485.0,13)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,14,985.0,14)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,15,1585.0,15)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,16,3585.0,16)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,17,5585.0,17)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,18,6585.0,18)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,19,8585.0,19)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,20,9585.0,20)
以及获取我正在使用的更改的SQL:
Select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
From #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
And ISNULL(A.StoreID,-1) <> ISNULL(B.StoreID,-1)
伙计们,有什么想法吗
提前谢谢
编辑:再多一点商业信息:ParentID就像一个商店,一个产品是什么,它到达那里的时间是什么。因此,假设productID 100位于ParentID 1中,这意味着在DateID 1中,productID 100输入了Store 1。所以出于某种原因,它移动到DateDod 4中的存储2。所以我在答案表中的第一行表示ProductID100在从DateID1到DateID4的StoreID1中。然后,productID 100从DateID 4保留到7,然后更改为StoredID 3,最后从DateID 9返回到StoredID 1,直到所选DateID范围内的最后一个DateID。这就是为什么答案表有两行ParentID为1的原因。好的,使用更新的样本数据尝试一下:
Declare @Trackings table
(
ProductID bigint
, value float
, StoreID int
, DateID int
, Aux_Row_Number int
)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,1,325.2,1)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,2,326.2,2)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,3,329.6,3)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,4,335.2,4)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,5,336.5,5)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,6,338.3,6)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,7,339.2,7)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,8,342.1,8)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,9,343.7,9)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,10,355.0,10)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,12,385.0,12)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,13,485.0,13)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,14,985.0,14)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,15,1585.0,15)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,16,3585.0,16)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,17,5585.0,17)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,18,6585.0,18)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,19,8585.0,19)
Insert into @Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,20,9585.0,20)
;
with t
as (select *, ROW_NUMBER() over (order by dateid) as rn
from @Trackings ),
cte1
(Productid,
Storeid,
DateID,
value,
rn,
set1)
as
(select ProductID, StoreID, DateID, value, rn , 1
from t
where rn = 1
union all
select t.productID, t.storeID, t.dateID, t.value, t.rn,
case when
cte1.Storeid = t.storeID then cte1.set1 else cte1.set1+1 end
from t join cte1 on t.rn = cte1.rn+1)
,
t2 as (select Productid, Storeid, set1, MIN(CAST(DateID as int)) as tmi, max(dateid) as tma
from cte1
group by Productid, Storeid, set1)
select t3.Productid, t3.Storeid, t3.set1, t3.date_min, t3.date_max, u.value - t.value
from
(select a.Productid, a.Storeid, a.set1, a.tmi as date_min, coalesce(b.tmi, a.tma) as date_max
from t2 a left join t2 b
on a.set1 + 1 = b.set1) t3 join @Trackings t
on t3.date_min = t.DateID
join @Trackings u
on t3.date_max = u.DateID
order by set1
值列让我很困惑,因为您使用的是逗号而不是句点。将整数与浮点小数部分分开。我终于找到了一个解决方案,它基于我的初始表,比使用CTE有更好的性能,正如实际表所建议的那样,它有5k个条目,使用his建议需要很长时间 查询搜索表之后,我为每个ProductID向表中添加了两行。这些行将接收一个虚拟的StoreID,即-9999:一个是MinDateID-1,另一个是MaxDateID+1
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Min(Aux_Row_Number)-1 Aux_Row_Number,-9999 as StoreID, min(DateID)-1 as DateID,ProductID,Min(value)
From #Trackings
group by ProductID
Order by ProductID
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Max(Aux_Row_Number)+1 Aux_Row_Number,-9999 as StoreID, max(DateID)+1 as DateID,ProductID,Max(value)
From #Trackings
group by ProductID
Order by ProductID
然后,我使用我发布的查询来获取更改。因此,我可以得到从Dummy-9999到real-StoreID 1的更改,以及从real-StoreID 3到Dummy-9999的最后一个更改
select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
, ROW_NUMBER() OVER (Partition by B.ProductID Order by A.DateID)
from #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
AND ISNULL(A.StoreID,0) <> ISNULL(B.StoreID ,0)
以下是最终解决方案:
IF OBJECT_ID('tempdb..#Trackings') Is Not Null
Drop table #Trackings
IF OBJECT_ID('tempdb..#ProductStoreChanges') Is Not Null
Drop table #ProductStoreChanges
Create Table #Trackings
(
ProductID bigint
, value float
, StoreID int
, DateID int
, Aux_Row_Number int
, flg_changed bit Default(0)
)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,1,325.2,1)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,2,326.2,2)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,3,329.6,3)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,4,335.2,4)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,5,336.5,5)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,6,338.3,6)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,7,339.2,7)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,8,342.1,8)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,9,343.7,9)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,10,355.0,10)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,12,385.0,12)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,13,485.0,13)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,14,985.0,14)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,15,1585.0,15)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,16,3585.0,16)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,17,5585.0,17)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,18,6585.0,18)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,19,8585.0,19)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,20,9585.0,20)
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Min(Aux_Row_Number)-1 Aux_Row_Number,-9999 as StoreID, min(DateID)-1 as DateID,ProductID,Min(value)
From #Trackings
group by ProductID
Order by ProductID
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Max(Aux_Row_Number)+1 Aux_Row_Number,-9999 as StoreID, max(DateID)+1 as DateID,ProductID,Max(value)
From #Trackings
group by ProductID
Order by ProductID
CREATE TABLE #ProductStoreChanges
(
ID_InitialStore INT
, ID_FinalStore INT
, ProductID INT
, value_1 BIGINT
, value_2 BIGINT
, DateID_Initial BIGINT
, DateID_Final BIGINT
, Aux_Row_Number INT
)
INSERT INTO #ProductStoreChanges
(
ID_InitialStore
, ID_FinalStore
, ProductID
, value_1
, value_2
, DateID_Initial
, DateID_Final
, Aux_Row_Number
)
select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
, ROW_NUMBER() OVER (Partition by B.ProductID Order by A.DateID)
from #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
AND ISNULL(A.StoreID,0) <> ISNULL(B.StoreID ,0)
select A.ID_FinalStore,A.DateID_Final,B.DateID_Final,A.ProductID,B.value_2,A.value_2,B.value_2 - A.value_2 DeltaValue
from #ProductStoreChanges A
Join #ProductStoreChanges B
On (A.Aux_Row_Number + 1 = B.Aux_Row_Number)
And A.ProductID = B.ProductID
Order by A.DateID_Final
在答案表中,最后一行的逻辑与前三行不同。第4行的TSID_端来自具有相同父级的记录。在其他行上,它来自下一个父级的第一条记录。这是预期的结果吗?这里有很好的细节,但示例和实际示例数据之间有点脱节,例如ObjectID和ProductID、辅助行号。。。在问题的这些不同部分之间有一致的数据和表结构是非常有用的。@Declan-k结果是这样的,因为它是最后一个可用的辅助行编号:。因此,在选定的间隔内,结果不会给我更多的选项,我们只需在TSID_End中添加间隔内最后一个可用的数字。@IanPreston感谢Man指出我愚蠢的错误!已编辑:已替换objectId以使ProductID保持一致!将使用Aux_Row_编号,因为我有不同的ProductSid,而且到目前为止我觉得有必要,但你是对的,我没有提供更多的细节。当我最终解决我的问题时,我会更新下面的帖子并检查!谢谢:嘿,迈克。谢谢你帮我。我正在尝试修改您的SQL代码以满足我的需要,但它不起作用。我编辑了帖子,并为这个案例添加了业务规则。如果我找到了解决方案,我也会在这里发布。谢谢
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Min(Aux_Row_Number)-1 Aux_Row_Number,-9999 as StoreID, min(DateID)-1 as DateID,ProductID,Min(value)
From #Trackings
group by ProductID
Order by ProductID
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Max(Aux_Row_Number)+1 Aux_Row_Number,-9999 as StoreID, max(DateID)+1 as DateID,ProductID,Max(value)
From #Trackings
group by ProductID
Order by ProductID
select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
, ROW_NUMBER() OVER (Partition by B.ProductID Order by A.DateID)
from #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
AND ISNULL(A.StoreID,0) <> ISNULL(B.StoreID ,0)
select A.ID_FinalStore,A.DateID_Final,B.DateID_Final,A.ProductID,B.value_2,A.value_2,B.value_2 - A.value_2 DeltaValue
from #ProductStoreChanges A
Join #ProductStoreChanges B
On (A.Aux_Row_Number + 1 = B.Aux_Row_Number)
And A.ProductID = B.ProductID
Order by A.DateID_Final
IF OBJECT_ID('tempdb..#Trackings') Is Not Null
Drop table #Trackings
IF OBJECT_ID('tempdb..#ProductStoreChanges') Is Not Null
Drop table #ProductStoreChanges
Create Table #Trackings
(
ProductID bigint
, value float
, StoreID int
, DateID int
, Aux_Row_Number int
, flg_changed bit Default(0)
)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,1,325.2,1)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,2,326.2,2)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,3,329.6,3)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,4,335.2,4)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,5,336.5,5)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,6,338.3,6)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,7,339.2,7)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,8,342.1,8)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,9,343.7,9)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,10,355.0,10)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,12,385.0,12)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,13,485.0,13)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,14,985.0,14)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,15,1585.0,15)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,16,3585.0,16)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,17,5585.0,17)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,18,6585.0,18)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,19,8585.0,19)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,20,9585.0,20)
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Min(Aux_Row_Number)-1 Aux_Row_Number,-9999 as StoreID, min(DateID)-1 as DateID,ProductID,Min(value)
From #Trackings
group by ProductID
Order by ProductID
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Max(Aux_Row_Number)+1 Aux_Row_Number,-9999 as StoreID, max(DateID)+1 as DateID,ProductID,Max(value)
From #Trackings
group by ProductID
Order by ProductID
CREATE TABLE #ProductStoreChanges
(
ID_InitialStore INT
, ID_FinalStore INT
, ProductID INT
, value_1 BIGINT
, value_2 BIGINT
, DateID_Initial BIGINT
, DateID_Final BIGINT
, Aux_Row_Number INT
)
INSERT INTO #ProductStoreChanges
(
ID_InitialStore
, ID_FinalStore
, ProductID
, value_1
, value_2
, DateID_Initial
, DateID_Final
, Aux_Row_Number
)
select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
, ROW_NUMBER() OVER (Partition by B.ProductID Order by A.DateID)
from #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
AND ISNULL(A.StoreID,0) <> ISNULL(B.StoreID ,0)
select A.ID_FinalStore,A.DateID_Final,B.DateID_Final,A.ProductID,B.value_2,A.value_2,B.value_2 - A.value_2 DeltaValue
from #ProductStoreChanges A
Join #ProductStoreChanges B
On (A.Aux_Row_Number + 1 = B.Aux_Row_Number)
And A.ProductID = B.ProductID
Order by A.DateID_Final