2017-03-16 17 views
2

我正在嘗試查找具有不同事務類型的行之後的特定事務類型的行。我遇到的問題是,有問題的表可以包含實體的每個事務類型的多個實例,並且我想按順序將事務配對。查找在SQL Server表的子集中的前一個值和下一個值之間的值

一旦我確定了事務對,然後我想從第一個事務類型複製日期值到第二個事務類型的匹配行。

這裏是一個演示該問題的表:

CREATE TABLE [dbo].[Example] 
(
    [EntityID] [INT] NOT NULL, 
    [TransactionSequenceNumber] [INT] NOT NULL, 
    [TransactionType] [VARCHAR](1) NOT NULL, 
    [TransactionDate] [DATETIME] NULL 
) ON [PRIMARY] 
GO 

INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (1, 1, 'A', '2017-01-01 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (1, 2, 'B', '2017-01-02 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (1, 3, 'C', NULL) 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (1, 4, 'B', '2017-01-03 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (1, 5, 'C', NULL) 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (1, 6, 'D', '2017-01-05 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (2, 1, 'A', '2017-02-01 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (2, 2, 'B', '2017-02-02 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (2, 3, 'C', NULL) 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (2, 4, 'B', '2017-02-10 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (2, 5, 'C', NULL) 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (2, 6, 'B', '2017-02-13 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (3, 1, 'A', '2017-03-01 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (3, 2, 'B', '2017-03-02 00:00:00') 
INSERT INTO dbo.Example (EntityID, TransactionSequenceNumber, TransactionType, TransactionDate) VALUES (3, 3, 'C', NULL) 

在本例中,我要更新的類型「C」的行與從前面的「B」型行的日期。

這裏是演示了這個安全漏洞與我當前的查詢選擇查詢:

SELECT 
    c.EntityID, c.TransactionSequenceNumber, c.TransactionType, 
    b.EntityID, b.TransactionSequenceNumber, b.TransactionDate 
FROM  
    dbo.Example c 
LEFT OUTER JOIN 
    (SELECT 
     EntityID, 
     TransactionSequenceNumber, 
     TransactionDate 
    FROM 
     dbo.Example 
    WHERE 
     TransactionType = 'B') b ON b.EntityID = c.EntityID 
            AND b.TransactionSequenceNumber < c.TransactionSequenceNumber 
WHERE 
    c.TransactionType = 'C' 
ORDER BY 
    c.EntityID, c.TransactionSequenceNumber 

你可以從結果中看到,每個「C」與每一個「B」,有一個較小的序列號相匹配。如何將我的查詢更改爲僅將每個'C'與前面的'B'配對?

感謝。

回答

3

您可以使用OUTER APPLY得到正確的日期:

SELECT * 
FROM dbo.Example A 
OUTER APPLY (SELECT TOP 1 * 
      FROM dbo.Example 
      WHERE EntityID = A.EntityId 
      AND TransactionSequenceNumber < A.TransactionSequenceNumber 
      AND TransactionType = 'B' 
      ORDER BY TransactionSequenceNumber DESC) B 
WHERE A.TransactionType = 'C' 
; 

如果要更新表的日期,然後使用:

UPDATE A 
SET A.TransactionDate = B.TransactionDate 
FROM dbo.Example A 
OUTER APPLY (SELECT TOP 1 * 
      FROM dbo.Example 
      WHERE EntityID = A.EntityId 
      AND TransactionSequenceNumber < A.TransactionSequenceNumber 
      AND TransactionType = 'B' 
      ORDER BY TransactionSequenceNumber DESC) B 
WHERE A.TransactionType = 'C' 
; 
+0

這就是我需要的到底是什麼。非常感謝! –

相關問題