我有一张没有主键的表。
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行。 请帮助我,如何实现这一点。
答案 0 :(得分:3)
你真正的问题是你没有行号,也没办法去掉相同的行。如果您的数据仍然按插入顺序排列,那么到目前为止您只是幸运。 SQL Server不保证行排序,可以随机化订单,恕不另行通知。要保留您的订购,您可以在表格中添加标识列。
ALTER TABLE TableWithNoPrimaryKey
ADD RowNum int IDENTITY(1,1) PRIMARY KEY
答案 1 :(得分:1)
不能在SQL中使用ROW_NUMBER函数,因为这些重复项可以分布在数千条记录中。 ROW_NUMBER用于获取带有OVER子句的行号,并且由于此类数据的存储未被删除,因此无法删除。 唯一的选择是向表中添加一些标识或唯一列,然后删除特殊记录,如果您不想要带有新索引或新列的表,则可以从表中删除该cloumn。
答案 2 :(得分: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');
答案 3 :(得分:0)
我已经将您的表名称视为T1,并更新了其中的一行。我不想订购结果集,但仍想生成行号,因此我使用了一个虚拟子查询-选择0。下面的查询在Oracle和IBM Netezza中有效。如果rowid存在于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;