如何为此SELECT查询编写UPDATE查询?

时间:2011-08-18 22:06:44

标签: mysql sql sql-update

我在上一个问题(link)中查询了一个复杂的选择, 我的问题是,如何为此查询的结果编写更新查询,将fet_id更改为某个新值。

请注意,此查询将从队列中选择行,直到rcpts_count达到1000(用于流量控制)。有关此查询的更多信息,in this question

   SELECT NULL AS msg_id, NULL AS total, NULL AS found
    FROM dual
     WHERE (
      @total :=0
       OR 
      @found :=0
    )
    UNION
      SELECT msg_id, @total AS total, @found :=1 AS found
        FROM messages_queue
      WHERE (
        @total := @total + rcpts_count
      )
    AND @total <1000
    UNION
      SELECT msg_id, rcpts_count AS total, 0 AS found
        FROM messages_queue
      WHERE IF( @found =0, @found :=1, 0 )

2 个答案:

答案 0 :(得分:0)

我看到你要求MySql。这是一个MsSql解决方案,但我认为语法非常接近(但不是100%肯定)。此示例已简化,因此可应用于任何Stack用户。希望您可以转换为您的特定数据集。

-- sample table
create table x 
    (col1 int identity(1, 1)
    ,col2 varchar(50))

-- sample data  
insert into x (col2) values
     (null)
    ,(null)
    ,(null)
    ,(null)
    ,(null)

-- update from select
update x
    set x.col2 = 'even'
from x as [t2]
where 
    col1 = t2.col1
    and t2.col1 % 2 = 0

-- show results
select * from x

-- clean up
drop table x

祝你好运。

答案 1 :(得分:0)

如果您尝试更新集合中的所有记录,可以编写如下查询:

UPDATE message_queue mq
INNER JOIN (
   SELECT NULL AS msg_id, NULL AS total, NULL AS found
    FROM dual
     WHERE (
      @total :=0
       OR 
      @found :=0
    )
    UNION
      SELECT msg_id, @total AS total, @found :=1 AS found
        FROM messages_queue
      WHERE (
        @total := @total + rcpts_count
      )
      AND @total <1000
    UNION
      SELECT msg_id, rcpts_count AS total, 0 AS found
      FROM messages_queue
      WHERE IF( @found =0, @found :=1, 0 )
) msgs ON msgs.msg_id = mq.msg_id
SET mq.fet_id = 12345;

但是,根据您的活动,这不是一种安全的方法,因为查询返回的记录可能会在两个请求之间发生变化。

我建议采用以下方法之一:

  • 处理应用程序端的更新
  • 使用查询结果创建临时表,并使用连接更新表到临时表
  • 假设'fet_id'是此批次唯一的密钥,请先运行update语句,然后根据fet_id进行简单的选择。