在SET关键字内运行SQL查询以设置查询返回的记录数

时间:2013-10-19 17:08:31

标签: mysql sql

在一个UPDATE查询中,是否可以SET基于SQL查询结果的值?

这是我想到的查询不起作用:

UPDATE items SET itemcode=CONCAT('XYZ',(SELECT COUNT(*) as ctr FROM items
       WHERE itemcode!=''),'GZ') WHERE itemid=123;

这不是实际查询,但是当我尝试运行两个连续查询时,使用一个查询的目的是防止竞争条件。

items表中插入记录后,我需要更新一些创建的项目并输入增量的项目代码。因此,它取决于表中具有空itemcode的项目数。

3 个答案:

答案 0 :(得分:2)

为了正确避免竞争条件,您可以使用LOCK TABLE和交易以确保结果一致。

在您的查询中

UPDATE items SET itemcode=CONCAT('XYZ',(SELECT COUNT(*) as ctr FROM items
   WHERE itemcode!=''),'GZ') WHERE itemid=123;

您正在从items

选择具有给定属性的记录
SELECT COUNT(*) as ctr FROM items WHERE itemcode!=''

然后将itemcode 123的itemid与XYZGZ相关联。

您也可以使用UPDATE JOINitems之间的ctr

UPDATE items JOIN ( 
   SELECT CONCAT('XYZ', COUNT(*), 'GZ') AS newcode FROM items
       WHERE itemcode!='') AS dummy
SET itemcode = dummy.newcode WHERE itemid = 123;

或者在MySQL中(并使用LOCK TABLES),您可以SELECT将计数转换为临时变量,然后将itemcode分配给该变量:

mysql> CREATE TABLE items ( itemid integer, itemcode varchar(32) );
mysql> INSERT INTO items VALUES ( 1, 'one' ), ( 2, 'two' ), ( 123, 'and 123');
mysql> LOCK TABLE items WRITE;
mysql> BEGIN WORK;
mysql> SELECT COUNT(*) INTO @x FROM items WHERE itemcode != '';
mysql> UPDATE items SET itemcode=CONCAT('XYZ',@x,'GZ') WHERE itemid = 123;
mysql> COMMIT WORK;
mysql> UNLOCK TABLES;


mysql> SELECT * FROM items;
+--------+----------+
| itemid | itemcode |
+--------+----------+
|      1 | one      |
|      2 | two      |
|    123 | XYZ3GZ   |
+--------+----------+
3 rows in set (0.00 sec)

一种较短的做法,没有显式锁定:

mysql> BEGIN WORK;
mysql> SELECT COUNT(*) INTO @x FROM items WHERE itemcode != '' FOR UPDATE;
mysql> UPDATE items SET itemcode=CONCAT('XYZ',@x,'GZ') WHERE itemid = 123;
mysql> COMMIT WORK;

答案 1 :(得分:0)

这是您可能想要用于此案例的查询示例:

UPDATE
    Table AS t
    LEFT JOIN (
        SELECT
            Index1,
            Index2,
            COUNT(EventType) AS NumEvents
        FROM
            MEvents
        WHERE
            EventType = 'A' OR EventType = 'B'
        GROUP BY
            Index1,
            Index2
    ) AS m ON
        m.Index1 = t.Index1 AND
        m.Index2 = t.Index2
SET
    t.SpecialEventCount = m.NumEvents
WHERE
    t.SpecialEventCount IS NULL

最初由@Hammerite here发布。

答案 2 :(得分:0)

找到了答案!

子查询不应该在SET部分内,因为我试图访问同一个表。问题中的查询返回以下错误:

#1093 – You can’t specify target table ‘items’ for update in FROM clause.

解决方案:

UPDATE items,(SELECT COUNT(*) as ctr FROM items WHERE itemcode!='') temp
        SET itemcode=CONCAT('XYZ',temp.ctr+1,'GZ') WHERE itemid=123;

来源: http://7php.com/mysql-update-select-statement-1093/