1

我有一张没有主键的表。

name      age       sex
a         12        m
b         61        m
c         23        f
d         12        m
a         12        m
a         12        m
f         14        f

我正好有 3 个相似的第 1 行、第 5 行和第 6 行。我想更新第 5 行而不影响第 1 行和第 6 行。请帮助我,如何实现这一目标。

4

4 回答 4

3

您真正的问题是您没有行号,也无法区分相同的行。如果您的数据仍然按照插入的顺序排列,那么到目前为止您已经很幸运了。SQL Server 不保证行排序,并且可以随机化顺序,恕不另行通知。为了保留您的顺序,您可以在表中添加一个标识列。

ALTER TABLE TableWithNoPrimaryKey
ADD RowNum int IDENTITY(1,1) PRIMARY KEY
于 2012-05-04T09:35:27.590 回答
1

有一种方法可以做你想做的事。虽然不推荐。

;WITH cte AS
(
    SELECT *, RowNum = ROW_NUMBER() OVER (ORDER BY GETDATE())
    FROM [table]
)
UPDATE cte
SET age = age + 1
WHERE (RowNum = 5)
AND (name = 'a' AND age = 12 AND sex = 'm');
于 2012-05-04T10:41:02.397 回答
1

它不可能在 SQL 中使用 ROW_NUMBER 函数,因为这种重复可以分布在数千条记录中。ROW_NUMBER 用于通过 OVER 子句获取行号,并且由于此类数据的存储是非集群的,因此无法删除。唯一的选择是向表中添加一些标识或唯一列,然后删除特殊记录,如果您不想要具有新索引或新列的表,您可以从表中删除该列。

于 2012-05-04T09:31:20.597 回答
0

我已将您的表名视为 T1 并更新了其中一行。我不想订购结果集但仍想生成行号,所以我使用了一个虚拟子查询 - 选择 0。下面的查询适用于 Oracle 和 IBM Netezza。如果它存在于 SQL SERVER 中,您可以尝试使用 rowid 或任何其他与 rowid 等效的东西。

UPDATE T1 SET name = a1, age = 21, sex = 'm'
FROM (SELECT name, age, sex, rowid,
row_number() over(partition by name, age, sex ORDER BY(SELECT 0)) as rn
FROM T1)A
WHERE T1.name = A.name 
AND T1.age = A.age
AND T1.sex = A.sex
AND T1.rowid = A.rowid 
AND A.rn = 1;
于 2019-09-04T06:25:32.573 回答