使用SQL UPDATE自动生成排序顺序

时间:2009-02-04 15:48:25

标签: sql sql-server-2005

我最近将大约60,000条记录导入到一个表中,该表将一个表中的数据与另一个表中的数据相关联。但是,我的客户已要求将排序顺序添加到所有60k记录中。我希望有一种很好的清洁方法可以在SQL Update中自动生成这些排序顺序。完成的数据应如下所示:

item1ID  item2ID  sortOrder
1           123       1
1           12        2
1           45        3
1           22        4
1           456       5
2           5         1
2           234       2
2           56        3

可以这样做吗?任何建议都会非常感激。

- 安

3 个答案:

答案 0 :(得分:10)

您可以使用[ROW_NUMBER] [1]并按Item1ID分区

UPDATE t1
SET t1.SortOrder = t2.SortOrder 
FROM @t t1
INNER JOIN
(SELECT Item1ID, Item2ID, ROW_NUMBER() OVER
    (PARTITION BY Item1ID ORDER BY Item1ID, Item2ID) AS SortOrder
from @t) t2
ON t1.Item1ID = t2.Item1ID 
AND t1.Item2ID = t2.Item2ID

答案 1 :(得分:1)

你在这里谈论关系模型的基本内容。在整个数据库中,没有内在的排序。如果您想在查看表时获得数据排序,则必须明确指定该顺序。

所以在一般意义上,你要求的是不可能的。您不能只是UPDATE一个表,并自动排序您对其所做的任何查询。但是在查询查询意义上,您始终可以在应用于表格的任何ORDER BY item1ID, sortOrder语句中添加“SELECT”。

在SQL Server 2005中,您可以编写一个视图并使用这个旧的hack将其呈现给您的客户端:

SELECT TOP 100 PERCENT
    item1ID, item2ID, sortOrder  -- and all the other columns
FROM YourTable
ORDER BY item1ID, sortOrder;

有一些方法可以让这种视图更新,但你需要自己研究。做起来并不难。

如果您永远不会在此表中插入或更改数据,并且您愿意再次将数据重新导入表中,则可以使用标识定义表,然后将数据插入表中适当的顺序。然后,您将始终通过一个标识列进行排序。如果您的客户端始终在允许按单列排序的程序中查看数据,那么这将起作用。 (顺便说一句,为此目的,永远不要使用IDENTITY 函数。它不起作用。)

CREATE TABLE YourTable (
    SingleSortColumn  INT IDENTITY(1,1) NOT NULL,
    ...
);
INSERT INTO YourTable (
    item1ID, item2ID, sortOrder  -- everything except the SingleSortColumn
)
SELECT  -- all your columns
INTO YourTable
FROM yadda yadda yadda
ORDER BY item1ID, sortOrder;

希望这有帮助。对不起,如果我是迂腐的。

答案 2 :(得分:0)

理论上,你可以说:

update mytable 
  set sortOrder = row_number() 
     over (partition by item1id order by item1id, item2id) from mytable

但是,这会给你一条错误信息:

Msg 4108, Level 15, State 1, Line 1
Windowed functions can only appear in the SELECT or ORDER BY clauses.

所以你实际上必须分两步完成 - 首先在临时表中选择值,然后从临时表中更新原始数据。

例如:

select 
    item1ID, 
    item2ID, 
    row_number() 
        over (partition by item1id order by item1id, item2id) as sortOrder 
  into #tmp 
  from mytable

update mytable 
  set sortOrder = T.sortOrder 
  FROM 
    mytable M 
    inner join #tmp T 
        on M.item1ID = T.item1ID 
        AND M.item2ID = T.item2ID

drop table #tmp