[英]How do I UPDATE TOP 5, using a subselect?
我惊讶地发现以下更新了34行...而不是5行:
UPDATE
Message
SET StatusRawCode = 25
WHERE StatusRawCode in
(
Select TOP 5
M2.StatusRawCode
From Message as M2
Where M2.StatusRawCode = 5
)
关于如何将其打造成正确形状的任何想法?
谢谢!
我的猜测是从您的子查询返回的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列值为您提供前5个记录。 您可以根据需要替换列。
有没有办法明确识别TOP 5行?
根据您的查询,如果您执行TOP 5并不重要(因为您选择StatusRawCode = 5的记录)。 所以,在某种程度上你的查询是相同的
UPDATE
Message
SET StatusRawCode = 25
WHERE StatusRawCode = 5
似乎StatusRawCode
远非唯一。 您想要撤回主键或其他唯一列以识别前五个。 您正在更新StatusRawCode
等于5的任何行。显然,有34行符合该条件。
此外, top 5
只表示任何带有order by
子句的东西。 SQL Server不以任何特定顺序存储行,并且不保证每次都返回相同的五行。 SQL Server以8k页为单位存储行,并且不保证也不为行集提供一致的顺序。 您不能依赖于此,您必须使用order by
来确保您获得正确的五行。 否则,您将更新五个随机行 。
您需要将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
我想介入并建议您始终使用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)...,那么你将无法得到你想要的结果。
抢
如果您没有主键且CTE不可用,则以下内容也适用:
UPDATE M
SET StatusRawCode = 25
FROM (Select TOP 5
M2.StatusRawCode
FROM Message as M2
WHERE M2.StatusRawCode = 5
ORDER BY ...) M
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.