2014-03-06 81 views
2
CREATE TABLE [Transaction](
    [TransactionID] [bigint] IDENTITY(1,1) NOT NULL, 
    [LocationID] [int] NOT NULL, 
    [KioskID] [int] NOT NULL, 
    [TransactionDate] [datetime] NOT NULL, 
    [TransactionType] [varchar](7) NOT NULL, 
    [Credits] [int] NOT NULL, 
    [StartingBalance] [int] NULL, 
    [EndingBalance] [int] NULL, 
    [SessionID] [int] NULL 
); 

請參閱本搗鼓樣本數據: Link to SQL Fiddle分配會議號碼一系列的交易

我試圖找出是否有一個會話編號分配序列的方法的交易在一次更新中。

「會話」定義爲以提款結束的存款和購買數量。甲會話具有由順序記錄:

  • 1至n沉積物(TRANSACTIONTYPE = 'd'),
  • 0到n購買(TRANSACTIONTYPE = 'P')和
  • 0或1個取款(TRANSACTIONTYPE ='W')

具有相同的LocationID和KioskID。會話可以以0結餘或退出結束。首先沒有會話的存款啓動一個。只有P交易有餘額。對於D和W,它們是NULL。

LocationID,KioskID,SessionID必須是唯一的。

我真的希望有這樣做的SQL方式。我討厭不得不循環數以億計的交易來程序化地設置會話。

+0

這是更多的業務邏輯的事情,我建議你在你的BL層實現。您可以通過檢查正在插入/更新的當前事務是否「關閉」會話並處理適當的操作來控制它。也許你可以找到有用的創建endsession timestatmp或標誌到你的會話表 – jean

+0

我無法控制數據輸入。我從幾百個現有地點收集它。 – Metaphor

+0

我已經向設備中的用戶提供了一個會話ID的請求,但最多隻有一年。 – Metaphor

回答

1

這應做到:

;WITH markSessions as 
(
    SELECT *, 
     CASE 
      WHEN TransactionType='W' THEN 1 
      WHEN TransactionType='P' And EndingBalance=0 THEN 1 
      ELSE 0 END As SessionEnd 
    FROM Transactions 
) 
SELECT *, 
    SUM(SessionEnd) OVER(PARTITION BY LocationID, KioskID ORDER BY TransactionID) 
     + 1 - SessionEnd As SessionID 
FROM markSessions 

沒有觸發器,遊標或者客戶端代碼需要。


如果你真的想設置的SessionID在表中,那麼你會使用UPDATE語句是這樣的:

;WITH markSessions as 
(
    SELECT *, 
     CASE 
      WHEN TransactionType='W' THEN 1 
      WHEN TransactionType='P' And EndingBalance=0 THEN 1 
      ELSE 0 END As SessionEnd 
    FROM Transactions 
) 
UPDATE markSessions 
SET SessionID = SUM(SessionEnd) OVER(PARTITION BY LocationID, KioskID ORDER BY TransactionID) 
     + 1 - SessionEnd 

我無法測試,但以下應考慮到預先存在SessionIDs

;WITH markSessions as 
(
    SELECT *, 
     CASE 
      WHEN TransactionType='W' THEN 1 
      WHEN TransactionType='P' And EndingBalance=0 THEN 1 
      ELSE 0 END As SessionEnd 
    FROM Transactions 
) 
UPDATE markSessions 
SET SessionID = SUM(SessionEnd) OVER(PARTITION BY LocationID, KioskID ORDER BY TransactionID) 
     + 1 - SessionEnd 
     + COALESCE(MAX(SessionID) OVER (PARTITION BY LocationID, KioskID), 0) 
WHERE SessionID Is NULL 

請注意,這隻會工作,如果所有新行(那些沒有SessionIDs)有比預先存在的行(已經具有SessionID的行)更高的事務ID。它肯定是不是如果添加了具有TransactionID的新行,它會低於已分配SessionID的最高TransactionID。

如果您可能有這種情況,那麼您可能將不得不重新分配舊的TransactionID。

+0

它的工作原理。儘管如此,我不能說我完全理解。另外,這將在每次運行時重新分配會話編號。數據每天添加,我想在後續運行時繼續SessionID。這是可行的嗎? – Metaphor