0

以下のような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 では、select ステートメントが含まれていると update が機能しません。それを行う他の方法はありますか?

4

2 に答える 2

0

上記のデータを見て、複数の値を持つものはattr30 に更新したいと思います。attr1attr2

その場合、クエリは存在する数をカウントする必要attr2があります。

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;

選択したのは、複製される数字の 1 つだけであるSELECT ... GROUP BY ... HAVINGほうが安定しているからです。SELECT attr1, attr2 FROM my_data GROUP BY attr1attr2attr1

GROUP BYの MySQL ドキュメントによると、を使用するときに mysql がどの値を選択するかは保証されませんGROUP BY

私は、DBA の StackExchange で、物議を醸しているGROUP BY.

attr1=3最小の行でattr3を0に設定することが確実にわかっている場合attr2、質問に対する答えは次のようになります。

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);

読み込まれたサンプル データは次のとおりです。

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>

最初に、複数の行を持つ attr1 の attr3 を 0 に変更しました

2 番目のクエリのテスト

サンプルをリロードして、2 番目のクエリを実行しましょう。

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>

試してみる !!!

于 2012-12-03T17:41:44.870 に答える
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;
于 2012-12-03T17:10:58.863 に答える