2014-06-14 21 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(认为他们)需要这个。 –

相关问题