2013-02-07 25 views
4

根据以往的记录值我使用SQL Server 2008的如何递增SQL

列的值,我有两个表:User_masterItem_master

存在用户与user_id说明 = 10

|---------| 
| user_id | 
|---------| 
| 10 | 
|---------| 

有5个项目与ITEM_ID = 20到24

|---------|---------|------------| 
| item_id | user_id | item_order | 
|---------|---------|------------| 
| 20 | 10 |  0  | 
|---------|---------|------------| 
| 21 | 10 |  0  | 
|---------|---------|------------| 
| 22 | 10 |  0  | 
|---------|---------|------------| 
| 23 | 10 |  0  | 
|---------|---------|------------| 
| 24 | 10 |  0  | 
|---------|---------|------------| 

有在Item_master一个多个列item_order(int)。 我想放置item_order = 0到4在所有这些行中只有一个查询。

可能吗?

编辑:

ITEM_ID不应该是为了。

例如,而不是20,21,22,23,24;它可能是20,25,31,47,58。

+2

一个非常简单的解决方法是从item_id中减去20并使用:'update item_master set item_order = item_id - 20'。 –

+0

是{'item_id'' user_id'}保证是唯一的? –

+0

@Ic,是的,这些是各个表的主键。 – RAS

回答

7

可以使用row_number()窗口功能越来越多的具有相同分配给每一行。子查询是必需的,因为您不能直接在set子句中使用窗口函数。

update im 
set  im.item_order = im.rn 
from (
     select row_number() over (partition by user_id 
            order by item_id) - 1 as rn 
     ,  * 
     from item_master 
     ) as im; 

Live example at SQL Fiddle.

3

外推一点点,因为{item_iduser_id}在表中唯一的,这里是一个通用的解决方案:

UPDATE m 
SET item_order = x.new_item_order 
FROM item_master m 
INNER JOIN (
    SELECT [item_id], [user_id], 
     (ROW_NUMBER() OVER (PARTITION BY [user_id] 
          ORDER BY [item_id]))-1 AS [new_item_order] 
    FROM item_master 
) x ON m.item_id = x.item_id AND m.user_id = x.user_id 

SQL Fiddle example

这将在item_id为了设置item_order列每个用户,从0开始。

+0

@Ic。感谢您的回答,但Andomar的答案要简单得多。 – RAS

+1

@RAS是的Andomar的答案比这个更简单一点,因为连接显然没有必要 –

1

我以为你会希望通过组用户生成的数量和item_order列已经存在,只是需要更新?

update IM 
    set item_order = t.RowNumber 
FROM Item_master IM 
INNER JOIN 
    (select item_id , user_id , ROW_NUMBER() over(PARTITION BY user_id order by item_id) -1 as 'RowNumber' from Item_master) T 
    ON T.item_id = IM.item_id