質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

1回答

5432閲覧

【MySQL】同一テーブルのデータを用いたUPDATE

tajix_japan

総合スコア132

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2016/11/13 13:10

編集2016/11/13 13:14

下記のような株価の表のテーブル stock があります。
株ID 1101-Tと1102-Tについて2016-11-09から2016-11-11までの3日間の株価表です。

code hajimene takane yasune owarine dekidaka date_no date
1101-T 1800 1802 1760 1777 1500 1 2016-11-09
1101-T 1810 1812 1790 1799 2500 2 2016-11-10
1101-T 1840 1842 1810 1789 3500 3 2016-11-11
1102-T 2800 2802 2760 2777 2500 1 2016-11-09
1102-T 0 0 0 0 0 2 2016-11-10
1102-T 2840 2842 2740 2747 4500 3 2016-11-11

上記の株価表の特長は、出来高が0だと価格成立してないため、価格(hajimene takane yasune owarine)がゼロになってしまうことです。

実際には前日終値と同等の価値があるため、出来高ゼロの時は、hajimene takane yasune owarine について前日終値を入力しようと思います。

下記のようにtemporary tableで処理しようとしたのですが、
1288 - The target table A2 of the UPDATE is not updatable
というエラーが出てしまいました。

create temporary table A1
(SELECT * FROM stock WHERE date_no=1);
UPDATE
(SELECT * FROM stock WHERE date_no=2) as A2,A1
SET
A2.hajimene=A1.owarine,A2.takane=A1.owarine,A2.yasune=A1.owarine,A2.owarine=A1.owarine
WHERE A1.code=A2.code and A2.dekidaka='0'

どのようにすれば当方の希望の入力ができるでしょうか?
よろしくお願いいたします。

環境は
Apache/2.2.15 (CentOS 6.7)
MySQL 5.6です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

sql

1UPDATE stock AS dist 2INNER JOIN stock AS org ON dist.code = org.code 3 AND dist.date = ADDDATE(org.date, 1) 4SET dist.hajimene = org.owarine, 5 dist.takane = org.owarine, 6 dist.yasune = org.owarine, 7 dist.owarine = org.owarine 8WHERE dist.dekidaka = 0;

実行結果

sql

1mysql> CREATE TABLE stock ( 2 -> code varchar(8), 3 -> hajimene int, 4 -> takane int, 5 -> yasune int, 6 -> owarine int, 7 -> dekidaka int, 8 -> date_no int, 9 -> date date 10 -> ); 11Query OK, 0 rows affected (0.03 sec) 12 13mysql> INSERT INTO stock VALUES 14 -> ('1101-T', 1800, 1802, 1760, 1777, 1500, 1, '2016-11-09'), 15 -> ('1101-T', 1810, 1812, 1790, 1799, 2500, 2, '2016-11-10'), 16 -> ('1101-T', 1840, 1842, 1810, 1789, 3500, 3, '2016-11-11'), 17 -> ('1102-T', 2800, 2802, 2760, 2777, 2500, 1, '2016-11-09'), 18 -> ('1102-T', 0, 0, 0, 0, 0, 2, '2016-11-10'), 19 -> ('1102-T', 2840, 2842, 2740, 2747, 4500, 3, '2016-11-11'); 20Query OK, 6 rows affected (0.00 sec) 21Records: 6 Duplicates: 0 Warnings: 0 22 23mysql> SELECT * FROM stock; 24+--------+----------+--------+--------+---------+----------+---------+------------+ 25| code | hajimene | takane | yasune | owarine | dekidaka | date_no | date | 26+--------+----------+--------+--------+---------+----------+---------+------------+ 27| 1101-T | 1800 | 1802 | 1760 | 1777 | 1500 | 1 | 2016-11-09 | 28| 1101-T | 1810 | 1812 | 1790 | 1799 | 2500 | 2 | 2016-11-10 | 29| 1101-T | 1840 | 1842 | 1810 | 1789 | 3500 | 3 | 2016-11-11 | 30| 1102-T | 2800 | 2802 | 2760 | 2777 | 2500 | 1 | 2016-11-09 | 31| 1102-T | 0 | 0 | 0 | 0 | 0 | 2 | 2016-11-10 | 32| 1102-T | 2840 | 2842 | 2740 | 2747 | 4500 | 3 | 2016-11-11 | 33+--------+----------+--------+--------+---------+----------+---------+------------+ 346 rows in set (0.00 sec) 35 36mysql> UPDATE stock AS dist 37 -> INNER JOIN stock AS org ON dist.code = org.code 38 -> AND dist.date = ADDDATE(org.date, 1) 39 -> SET dist.hajimene = org.owarine, 40 -> dist.takane = org.owarine, 41 -> dist.yasune = org.owarine, 42 -> dist.owarine = org.owarine 43 -> WHERE dist.dekidaka = 0; 44Query OK, 1 row affected (0.00 sec) 45Rows matched: 1 Changed: 1 Warnings: 0 46 47mysql> SELECT * FROM stock; 48+--------+----------+--------+--------+---------+----------+---------+------------+ 49| code | hajimene | takane | yasune | owarine | dekidaka | date_no | date | 50+--------+----------+--------+--------+---------+----------+---------+------------+ 51| 1101-T | 1800 | 1802 | 1760 | 1777 | 1500 | 1 | 2016-11-09 | 52| 1101-T | 1810 | 1812 | 1790 | 1799 | 2500 | 2 | 2016-11-10 | 53| 1101-T | 1840 | 1842 | 1810 | 1789 | 3500 | 3 | 2016-11-11 | 54| 1102-T | 2800 | 2802 | 2760 | 2777 | 2500 | 1 | 2016-11-09 | 55| 1102-T | 2777 | 2777 | 2777 | 2777 | 0 | 2 | 2016-11-10 | 56| 1102-T | 2840 | 2842 | 2740 | 2747 | 4500 | 3 | 2016-11-11 | 57+--------+----------+--------+--------+---------+----------+---------+------------+ 586 rows in set (0.00 sec)

ただし、このSQLでは「出来高ゼロ」の日が2日以上 連続している場合、最初の日の値しか更新できません。
どういうことかと言うと、例えばcode = 1101-Tのデータが以下のようになっていた場合、

sql

1+--------+----------+--------+--------+---------+----------+---------+------------+ 2| code | hajimene | takane | yasune | owarine | dekidaka | date_no | date | 3+--------+----------+--------+--------+---------+----------+---------+------------+ 4| 1101-T | 1840 | 1842 | 1810 | 1789 | 3500 | 3 | 2016-11-11 | 5| 1101-T | 0 | 0 | 0 | 0 | 0 | 4 | 2016-11-12 | 6| 1101-T | 0 | 0 | 0 | 0 | 0 | 5 | 2016-11-13 | 7+--------+----------+--------+--------+---------+----------+---------+------------+

上記SQLの実行後は以下のようにしかならない、ということです。

sql

1+--------+----------+--------+--------+---------+----------+---------+------------+ 2| code | hajimene | takane | yasune | owarine | dekidaka | date_no | date | 3+--------+----------+--------+--------+---------+----------+---------+------------+ 4| 1101-T | 1840 | 1842 | 1810 | 1789 | 3500 | 3 | 2016-11-11 | 5| 1101-T | 1789 | 1789 | 1789 | 1789 | 0 | 4 | 2016-11-12 | 6| 1101-T | 0 | 0 | 0 | 0 | 0 | 5 | 2016-11-13 | 7+--------+----------+--------+--------+---------+----------+---------+------------+

日次のバッチ処理で当日分(あるいは前日分)のデータだけを更新したいなら、これで十分です。

もし、そうでないのであれば、上記SQLを
「更新された行数(※)が0行になるまで繰り返し実行する」
などの対処が必要になります。

※SQL実行後に表示されるRows matched: 1 Changed: 1 Warnings: 0Changed: nという部分

投稿2016/11/13 17:04

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tajix_japan

2016/11/13 19:13

有難うございます。 私にはとても思いつかない方法でした。 わざわざテーブル作ってテストまでして頂いて。 本当に感謝いたします。 有難うございました。 助かりました。有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問