4

SQL Server 2008 R2 でこれをどのように結論付けるかについては疑問があります。

いくつかの入力を持つテーブルがあり、この入力には親タグとタイムスタンプがあります。

これらのオブジェクトの親タグがタイムスタンプで変更されている場合があります。この親タグは時々変更される可能性があります。以下のテーブルがあるとしましょう。私の現在のテーブルには、さまざまな ObjectID を持つ何百万ものデータがあります。表を見ると、タイムスタンプ 3 から 4、6 から 7、8 から 9 で ParentID が変更されていることが簡単にわかります。

ProductID      ParentID       DateID          value
--------       ---------      -------         ------------- 
  100            1              1                325,2
  100            1              2                326,2
  100            1              3                329,6
  100            2              4                335,2
  100            2              5                336,5
  100            2              6                338,3
  100            3              7                339,2
  100            3              8                342,1
  100            1              9                343,7
  100            1              10               355,6
  100            1              11               385,8

私が望む答えは、ObjectID が属していた ParentID と、開始と終了のタイムスタンプ、およびタイムスタンプ間のデルタ値 (タイムスタンプ = TS) です。

ProductID      ParentID       DateID_Start   DateID_End   DeltaValue
  --------      ---------     ----------     --------     ---------- 
  100           1             1              4            10,0
  100           2             4              7            4,0
  100           3             7              9            4,5
  100           1             9              11           42,1

これまでに達成したことは、変更があったときに取得することですが、変更のみを提供し、上の表は提供しません。

ObjectID      ParentID_Old   ParentID_New    DateID_Changed   
  --------      ------------   ------------  ------------
  100           1              2              3 to 4
  100           2              3              6 to 7
  100           3              1              8 to 9

テーブルとテスト挿入を生成するコードは次のとおりです。以下は、変更を取得するための選択です。

        --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)

ライトのアイデアはありますか?

前もって感謝します!

EDITED: もう少し「ビジネス」情報: ParentID は、商品がある店舗のようなもので、DateID は商品がそこに到着した時刻です。したがって、productID 100 が ParentID 1 にあるとします。これは、DateID 1 で productID 100 が Store 1 に入力されたことを意味します。したがって、何らかの理由で DatedID 4 の Store 2 に移動しました。したがって、回答テーブルの最初の行は、 ProductID 100 は、DateID 1 から DateID 4 まで StoreID 1 にありました。productID 100 は、DateID 4 から 7 まで StoredID 2 にとどまり、次に StoredID 3 に変更され、最後に DateID 9 から最後まで StoreID 1 に戻りました。 「選択された」DateID 範囲の DateID。そのため、回答テーブルには ParentID 1 の 2 つの行があります。

4

2 に答える 2

0

私は最終的に、 CTEを使用するよりもパフォーマンスが優れている初期テーブルに基づくソリューションを見つけました。時間がかかります)。

検索テーブルにクエリを実行した後、ProductID ごとにテーブルに 2 つの行を追加しました。これらの行は、ダミーの StoreID (つまり -9999) を受け取ります。1 つは Min(DateID) - 1 で、もう 1 つは Max(DateID) + 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) から実際の StoreID (1) への変更と、実際の 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)

これが重要なステップでした。これで、探していた変更の DateID を使用して結果テーブルを作成できるようになりました。Aux_Row_Number 列は、次を使用して各製品への変更のシーケンスを取得するのに役立ちました (最後のクエリでテーブル #ProductStoreChanges が作成されたと考えてください。以下にソリューション全体を投稿します)。

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
于 2013-08-16T21:32:33.147 に答える