我很惊讶地发现以下更新了34行...而不是5行:
UPDATE
Message
SET StatusRawCode = 25
WHERE StatusRawCode in
(
Select TOP 5
M2.StatusRawCode
From Message as M2
Where M2.StatusRawCode = 5
)
关于如何将其打造成正确形状的任何想法?
谢谢!
答案 0 :(得分:4)
我的猜测是从您的子查询返回的StatusRawCode值是在更新的34条记录中使用的值。而不是
WHERE StatusRawCode IN
使用此:
UPDATE
Message
SET StatusRawCode = 25
WHERE PrimaryKey in
(
Select TOP 5
PrimaryKey
From Message as M2
Where M2.StatusRawCode = 5
)
实际上,您将在子查询中选择要更新的5行的主键。请记住,这将根据表的聚簇索引顺序仅更新前5条记录。如果需要为TOP 5记录指定特定条件,则需要添加order by子句。
例如,如果您要将一个名为Rank的列用作条件,请按以下方式编写查询:
UPDATE
Message
SET
StatusRawCode = 25
WHERE
PrimaryKey IN
(
SELECT TOP 5
PrimaryKey
FROM
Message as M2
WHERE
M2.StatusRawCode = 5
ORDER BY
Rank DESC
)
这将根据Rank列值为您提供TOP 5记录。您可以根据需要替换列。
答案 1 :(得分:2)
有没有办法明确识别TOP 5行?
根据您的查询,如果您执行TOP 5并不重要(因为您选择StatusRawCode = 5的记录)。因此,在某种程度上,您的查询与
相同UPDATE
Message
SET StatusRawCode = 25
WHERE StatusRawCode = 5
答案 2 :(得分:2)
StatusRawCode
似乎远非独一无二。您想要撤回主键或其他唯一列以识别前五个。您正在更新StatusRawCode
等于5的任何行。显然,有34行符合该条件。
此外,top 5
仅表示具有order by
子句的任何内容。 SQL Server不会以任何特定顺序存储行,并且不会保证每次都返回相同的五行。 SQL Server将行存储在8k页中,并且它不保证也不提供行集的一致顺序。您不能依赖于此,并且必须使用order by
以确保您获得正确的五行。否则,您将更新五个随机行。
答案 3 :(得分:1)
您需要将IN条件置于唯一的主键上。
在SQL 2K5和转发版中,您还可以使用CTE:
WITH cte AS (
Select TOP 5
M2.StatusRawCode
From Message as M2
Where M2.StatusRawCode = 5
ORDER BY ...
)
UPDATE cte
SET StatusRawCode = 25
答案 4 :(得分:0)
我想介入并建议您始终使用SELECT语句启动UPDATE语句。像这样:
SELECT *
--UPDATE m SET StatusRawCode = 25
FROM Message m
WHERE StatusRawCode in (
Select TOP 5
M2.StatusRawCode
From Message as M2
Where M2.StatusRawCode = 5
);
...但是一旦你可以看到你出错的地方(在这种情况下,可能与KG的回应类似),肯定会根据你的实际要求修改你的查询。
这将显示将受您的查询影响的行...所以一旦你有了正确的,更改UPDATE行的SELECT *(当前已注释),你应该得到可预测的结果。
请记住,UPDATE不支持ORDER BY,所以如果你最终尝试UPDATE TOP(5)...,那么你将无法得到你想要的结果。
罗布
答案 5 :(得分:0)
如果您没有主键且CTE不可用,则以下内容也适用:
UPDATE M
SET StatusRawCode = 25
FROM (Select TOP 5
M2.StatusRawCode
FROM Message as M2
WHERE M2.StatusRawCode = 5
ORDER BY ...) M