繁体   English   中英

如何使用subselect更新TOP 5?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM