2014-06-14 25 views
1

假設我有一個名爲[transactions]的表,其中標識列是主鍵,日期字段和其他一些列。我想要包含一個持續的列,這個列被計算或以某種方式計算,這將有效地存儲「排序順序」。但是,這不能簡單地作爲ID列,因爲我按日期排序,有時候可以追溯地添加一個值。在SQL Server中存儲維護排序索引的計算列的最佳方法是什麼?

因此,舉例來說,如果表開始了尋找這樣的:

+-----+------------+---------+--------+--------+ 
| id | date | account | amount | (sort) | 
+-----+------------+---------+--------+--------+ 
| 1 | 2014-05-22 |  7 | 100.00 | 1 | 
| 2 | 2014-05-29 |  7 | 45.25 | 2 | 
| 3 | 2014-06-03 |  8 | 99.00 | 3 | 
+-----+------------+---------+--------+--------+ 

然後,如果我遇到這樣的說法:

INSERT INTO [transactions] ([date], [account], [amount]) 
VALUES ('2014-05-27', 8, 88.50); 

我想排序列是聰明足以使該表會再看看這樣的:

+-----+------------+---------+--------+--------+ 
| id | date | account | amount | (sort) | 
+-----+------------+---------+--------+--------+ 
| 1 | 2014-05-22 |  7 | 100.00 | 1 | 
| 2 | 2014-05-29 |  7 | 45.25 | 3 | 
| 3 | 2014-06-03 |  8 | 99.00 | 4 | 
| 4 | 2014-05-27 |  8 | 88.50 | 2 | 
+-----+------------+---------+--------+--------+ 

理想情況下,我想這個專欄堅持爲ACTUA l列。什麼是實現這一目標的最佳方式?

+3

存儲此列的目的是什麼?你打算如何使用它?如果要進行物理存儲,則需要使用觸發器進行維護,因爲持久計算的列不會執行此操作,但可以在運行時使用「row_number」進行計算而不存儲它。 –

+0

'sort'是爲了保持排序順序,還是爲了計算行數?如果前者,可能有其他一些方法來存儲更容易維護的信息。 –

+0

爲了更容易分頁與大型數據集。 IMO MySQL的'LIMIT'子句處理分頁的能力比SQL Server的'ROW_NUMBER()'和伴隨子查詢要好得多。另外 - 考慮一下 - 如果我要在'[日期]'列創建一個非聚集索引,那麼這個「排序」數字已經作爲該索引的一部分計算在某處。我只是希望有一個簡單的方法來訪問它。 – SoaperGEM

回答

3

您可以直接計算出的值,當你需要它:

select t.*, row_number() over (order by [date]) as [sort] 
from transactions t; 

或者,只是使用[date]order by。我不明白爲什麼需要另一列。

編輯:

如果你想保留列sort才能,那麼你將需要一個觸發。而且,觸發器不會便宜。在觸發邏輯將基本上是:

update transactions 
    set sort = sort + 1 
    where [date] > NEWDATE; 

insert into transactions(. . . , [sort]) 
    select . . . , coalesce(max([sort])) + 1 
    from transactions 
    where [date] < NEWDATE; 

(我要離開了所有參與定義觸發的東西。)

雖然insert可以製成非常有效使用索引,這樣做影響update的性能,因爲它必須影響每一行以更大的日期。如果你幾乎總是插入更新的日期,這可能是一個合理的折衷。

+3

另一列的一種可能的用例可能是將其索引並有效地尋找行1000000至1000010。 –

+1

@MartinSmith。 。 。具有諷刺意味的是,'select'節省的代價是在每個'insert' /'delete'上花費更多的工作量。在某些情況下,這是合理的價格。 –

+1

事實上,如果先前插入單個行然後是最小的行,那麼表中的所有行都會得到更新!很高興知道爲什麼OP(認爲他們)需要這個。 –

相關問題