如何使用同一个表的子查询更新mysql中的表

时间:2012-12-03 16:58:43

标签: mysql ruby-on-rails

我有一个名为 my_data 的表格,如下所示:

 +-------+-------+--------+
 | attr1 | attr2 | att3   |
 +-------+-------+--------+
 |   3   |   1   |    1   |
 |   4   |   2   |    1   |
 |   5   |   3   |    1   |
 |   3   |   6   |    1   |
 |   3   |   7   |    1   |
 |   3   |   8   |    1   |
 |   8   |   8   |    1   |
 |   9   |   7   |    1   |
 |   3   |   9   |    1   |
 +-------+-------+--------+

我需要这样做:

UPDATE my_data 
SET 
    attr3 = 0 
WHERE (attr1, attr2) IN (SELECT attr1, attr2 FROM my_data GROUP BY attr1);

在mysql中,update不能与select语句一起使用。还有其他办法吗?

2 个答案:

答案 0 :(得分:0)

您可以使用内部查询加入my_data并更新attr3,如下所示:

UPDATE my_data a
JOIN (SELECT attr1, attr2 FROM my_data GROUP BY attr1) b
ON a.attr1 = b.attr1 AND a.attr2 = b.attr1
SET a.attr3 = 0;

答案 1 :(得分:0)

盯着上述数据,我猜您希望将attr3更新为任何有attr1attr2attr2的{​​{1}}。

如果是这种情况,查询应计算有多少UPDATE (SELECT attr1,COUNT(attr2) attr2count FROM my_data GROUP BY attr1 HAVING COUNT(attr2) > 1) A INNER JOIN my_data B USING (attr1) SET B.attr3 = 0;

SELECT ... GROUP BY ... HAVING

我之所以选择SELECT attr1, attr2 FROM my_data GROUP BY attr1是因为attr2 attr1中的GROUP BY只是attr1=3重复的数字之一,因此更加稳定。

根据attr2上的MySQL文档,there is no guarantee which value mysql chooses when using GROUP BY

I had answered a question in the DBA StackExchange about this controversial reliance on the order of a GROUP BY.

如果您确定要UPDATE (SELECT attr1,MIN(attr2) attr2 FROM my_data GROUP BY attr1 HAVING COUNT(attr2) > 1) A INNER JOIN my_data B USING (attr1,attr2) SET B.attr3 = 0; 确定具有最小drop database if exists clickit; create database clickit; use clickit create table my_data (attr1 INT,attr2 INT,attr3 INT); insert into my_data values (3,1,1),(4,2,1),(5,3,1), (3,6,1),(3,7,1),(3,8,1), (8,8,1),(9,7,1),(3,9,1); 的行是将attr3设置为0,那么您的问题的答案将是:

mysql> drop database if exists clickit;
Query OK, 1 row affected (0.12 sec)

mysql> create database clickit;
Query OK, 1 row affected (0.00 sec)

mysql> use clickit
Database changed
mysql> create table my_data (attr1 INT,attr2 INT,attr3 INT);
Query OK, 0 rows affected (0.07 sec)

mysql> insert into my_data values
    -> (3,1,1),(4,2,1),(5,3,1),
    -> (3,6,1),(3,7,1),(3,8,1),
    -> (8,8,1),(9,7,1),(3,9,1);
Query OK, 9 rows affected (0.05 sec)
Records: 9  Duplicates: 0  Warnings: 0

mysql> select * from my_data;
+-------+-------+-------+
| attr1 | attr2 | attr3 |
+-------+-------+-------+
|     3 |     1 |     1 |
|     4 |     2 |     1 |
|     5 |     3 |     1 |
|     3 |     6 |     1 |
|     3 |     7 |     1 |
|     3 |     8 |     1 |
|     8 |     8 |     1 |
|     9 |     7 |     1 |
|     3 |     9 |     1 |
+-------+-------+-------+
9 rows in set (0.00 sec)

mysql>

让我们测试它们:

测试第一个查询

首先是样本数据:

mysql>     UPDATE
    ->         (SELECT attr1,COUNT(attr2) attr2count FROM my_data
    ->         GROUP BY attr1 HAVING COUNT(attr2) > 1) A
    ->         INNER JOIN my_data B USING (attr1)
    ->     SET B.attr3 = 0;
Query OK, 5 rows affected (0.10 sec)
Rows matched: 5  Changed: 5  Warnings: 0

mysql>     select * from my_data;
+-------+-------+-------+
| attr1 | attr2 | attr3 |
+-------+-------+-------+
|     3 |     1 |     0 |
|     4 |     2 |     1 |
|     5 |     3 |     1 |
|     3 |     6 |     0 |
|     3 |     7 |     0 |
|     3 |     8 |     0 |
|     8 |     8 |     1 |
|     9 |     7 |     1 |
|     3 |     9 |     0 |
+-------+-------+-------+
9 rows in set (0.00 sec)

mysql>

以下是加载的示例数据:

mysql> drop database if exists clickit;
Query OK, 1 row affected (0.04 sec)

mysql> create database clickit;
Query OK, 1 row affected (0.00 sec)

mysql> use clickit
Database changed
mysql> create table my_data (attr1 INT,attr2 INT,attr3 INT
Query OK, 0 rows affected (0.07 sec)

mysql> insert into my_data values
    -> (3,1,1),(4,2,1),(5,3,1),
    -> (3,6,1),(3,7,1),(3,8,1),
    -> (8,8,1),(9,7,1),(3,9,1);
Query OK, 9 rows affected (0.05 sec)
Records: 9  Duplicates: 0  Warnings: 0

mysql> select * from my_data;
+-------+-------+-------+
| attr1 | attr2 | attr3 |
+-------+-------+-------+
|     3 |     1 |     1 |
|     4 |     2 |     1 |
|     5 |     3 |     1 |
|     3 |     6 |     1 |
|     3 |     7 |     1 |
|     3 |     8 |     1 |
|     8 |     8 |     1 |
|     9 |     7 |     1 |
|     3 |     9 |     1 |
+-------+-------+-------+
9 rows in set (0.00 sec)

mysql>     UPDATE
    ->         (SELECT attr1,MIN(attr2) attr2 FROM my_data
    ->         GROUP BY attr1 HAVING COUNT(attr2) > 1) A
    ->         INNER JOIN my_data B USING (attr1,attr2)
    ->     SET B.attr3 = 0;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from my_data;
+-------+-------+-------+
| attr1 | attr2 | attr3 |
+-------+-------+-------+
|     3 |     1 |     0 |
|     4 |     2 |     1 |
|     5 |     3 |     1 |
|     3 |     6 |     1 |
|     3 |     7 |     1 |
|     3 |     8 |     1 |
|     8 |     8 |     1 |
|     9 |     7 |     1 |
|     3 |     9 |     1 |
+-------+-------+-------+
9 rows in set (0.00 sec)

mysql>

这是我建议的第一个查询:

{{1}}

对于有多行的attr1,第一个将attr3更改为0

测试第二个查询

让我们重新加载示例并运行第二个查询:

{{1}}

试一试!!!