人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

MYSQLテーブルのUPDATEについて

DBからTABLEAを読み込んでおいて、そのデータを違うテーブルに格納したい(常にデータをIDごとに最新の1件としたい)と思い、
以下URLを参考にやってみたのですが、うまく動いてくれません。
http://naruhodo.television.co.jp/qa4380807.html?check_ok=1
プログラムについてご教授願ください。
[MYSQL5.1 PHP5.2]

// 接続
require_once("conn.php");

// SQL
$result = mysql_query("SELECT id, name, sum(price) AS price FROM TABLEA GROUP BY id");

// 変数格納&DB書き換え
while ($row = mysql_fetch_array($result)) {
$ins_sql[] = "UPDATE TABLEA SET
id = '".$row[id]."',
name = '".$row[name]."',
price = '".$row[price]."'";
}

for ($i=0; $i < count($ins_sql); $i++){
$res = mysql_query($ins_sql[$i]);

●質問者: dekapurio
●カテゴリ:ウェブ制作
✍キーワード:AS dB GROUP MySQL name
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● きゃづみぃ
●100ポイント

基本的に 何がうまく行かないのか書いてもらったほうがいい。

ここで なんとかというエラーが出るとか・・・。

で質問のプログラムを見ると 違うテーブルに格納すると言いながら

>UPDATE TABLEA SET

となっています。

これでは TABLEA に格納されてしまうことになりますので、最低限 テーブル名を別のものに

したほうがいいでしょう。

http://dev.mysql.com/doc/refman/4.1/ja/update.html

UPDATE [LOW_PRIORITY] [IGNORE] tbl_name

SET col_name1=expr1 [, col_name2=expr2 ...]

[WHERE where_definition]

[ORDER BY ...]

[LIMIT row_count]

◎質問者からの返答

>ここで なんとかというエラーが出るとか

phpを実行するとエラーは出ませんが、データがDBへ格納されていない状態です。

>これでは TABLEA に格納されてしまうことになります

申し訳ないですが、これも記載ミスです。

・・・AS price FROM TABLEB GROUP BY id

が正解でした。


2 ● ko8820
●20ポイント

>phpを実行するとエラーは出ませんが、データがDBへ格納されていない状態です

明示的にcommitを発行してみては?

あと、UPDATEはすでにレコードがない場合は更新されません。

今回の場合はINSERT文を使うのでは?

◎質問者からの返答

>明示的にcommitを発行してみては?

ごめんなさい、当方初心者なもので意味が解りません。

>今回の場合はINSERT文を使うのでは?

INSERT文でも上書きできますかね?


3 ● aside
●50ポイント
// 接続
require_once("conn.php");
// SQL
$result = mysql_query("SELECT id, name, sum(price) AS price FROM TABLEB GROUP BY id");
// 変数格納&DB書き換え
while ($row = mysql_fetch_array($result)) {
 $rs = mysql_query("SELECT COUNT(*) FROM TABLEA WHERE id = '".$row[id]."'");
 $cnt = 0;
 while ($row = mysql_fetch_array($rs)) { $cnt++; }
 if ($cnt) {
 $res = mysql_query("UPDATE TABLEA SET id = '".$row[id]."',name = '".$row[name]."',price = '".$row[price]."'");
 } else {
 $res = mysql_query("INSERT INTO TABLEA (id,name,price) VALUES ('".$row[id]."','".$row[name]."','".$row[price]."')");
 }
}
◎質問者からの返答

回答ありがとうございます。

書き方等大変参考になりました。


4 ● aside
●50ポイント

これをまねよう

http://q.hatena.ne.jp/1255584952

http://q.hatena.ne.jp/1164377582

◎質問者からの返答

同じような質問が出ていましたね。

参考になりました。


5 ● Km1967
●300ポイント ベストアンサー

標準的SQLであれば、面倒なのだがテーブルBに既存のid=1にはUPDATE、テーブルBに存在しないid=2にはINSERTで対処するという二段階になる。

だがMySQLにはINSERTとUPDATEの両方を併せ持つようなREPLACEというものが用意されておるから1発だ。


まずは、テーブルAからid毎の最新の一件を抽出する事を考える。これは以前のものの再利用だ。以前よりシンプルですむぞ。

SET @id = '', @c = 0;

SELECT id, date, price
FROM (
 SELECT *
 , IF(@id <> id, @c := 1, @c := @c + 1) c
 , IF(@id <> id, @id := id, @id := @id) i
 FROM テーブルA
 ORDER BY id, date DESC
) a
WHERE c = 1;

最新を抜き出せる事が確認できたなら本番だ。上記に1行加えるだけだ。

SET @id = '', @c = 0;

REPLACE INTO テーブルB
SELECT id, date, price
FROM (
 SELECT *
 , IF(@id <> id, @c := 1, @c := @c + 1) c
 , IF(@id <> id, @id := id, @id := @id) i
 FROM テーブルA
 ORDER BY id, date DESC
) a
WHERE c = 1;

http://dev.mysql.com/doc/refman/5.1/ja/replace.html


REPLACEを使う場合に注意せねばならぬのはPRIMARY KEYだ。以下の状態を想定しておる。

CREATE TEMPORARY TABLE テーブルB(id INT, date INT, price INT, PRIMARY KEY(id));

id毎に最新の1件しか入れぬのだからキーはidだけで十分という事だ。

テーブルAのPRIMARY KEYは今回は問題とはならぬが、処理速度面からインデックスはついているほうがいいだろう。

◎質問者からの返答

回答有難うございます。

素晴らしいです。結果、パーフェクトでした。

UPDATEも、新規IDに対してのINSERTもできていました。

REPLACE構文はわたしの教科書には無いものでしたので、とても勉強になりました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ