SQLでのデータの追加・更新方法について

このQ&Aのポイント
  • SQL文のREPLACE INTOを使用して既存データを削除してからデータを追加する方法を教えてください。
  • テーブルのキーをidではなくuser_idに設定して、既存データがある場合にはデータを更新する方法を教えてください。
  • idをそのまま残しつつ、user_idが既存かどうかを判定してデータを追加または更新する方法を教えてください。
回答を見る
  • ベストアンサー

REPLACE INTOみたいな

REPLACE INTO test(id, name) VALUES(2, 'ほげ'); とやるとkeyがidの場合既にid2があれば一度削除してから登録 されますよね。 keyはidというのを前提で以下のようなテーブルだとします。 id,user_id,name 1,3,ほげ 2,5,ほげほげ 3,9,ほげほげほげ user_idが既に存在する場合REPLACE INTOと同様な事をしたいのですが どのようにすれば可能でしょうか? 単純にidを外しuser_idをkeyにしてしまえば簡単なのですがidは そのまま残したいと思っております。 また、古典的な方法ですが既にuser_idがあるかを判別しif,elseで INSERT,UPDATEを書けば・・・という方法も考えたのですが簡単に できる方法はないかと思っております。 宜しくお願い致します!

  • dcx147
  • お礼率33% (214/636)
  • PHP
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

いまいち状況がわかりませんが user_idはユニーク属性がついているということでよいのでしょうか? そうであればINSERT IGNORE INTOして、UPDATEするとよいでしょう

dcx147
質問者

お礼

お返事ありがとうございます。 既に主キーをつけていたのでダメかと思い込んでいたのですが ユニークキーも合わせてつける事ができるのですね! おかげさまで無事解決です!ありがとうございました。

関連するQ&A

  • 階層構造のテーブルの行の取得について

    このジャンルでお願いします。 次のようなテーブルで CREATE TABLE IF NOT EXISTS user ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(32) NOT NULL, PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO user (name) VALUES ('user1'); INSERT INTO user (name) VALUES ('user2'); INSERT INTO user (name) VALUES ('user3'); CREATE TABLE IF NOT EXISTS item ( id int(11) NOT NULL AUTO_INCREMENT, parent_id INT, name varchar(32) NOT NULL, FOREIGN KEY (parent_id) REFERENCES item(id) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO item (parent_id, name) VALUES (null, 'item1'); INSERT INTO item (parent_id, name) VALUES (1, 'item2'); INSERT INTO item (parent_id, name) VALUES (2, 'item3'); INSERT INTO item (parent_id, name) VALUES (3, 'item4'); INSERT INTO item (parent_id, name) VALUES (2, 'item5'); INSERT INTO item (parent_id, name) VALUES (null, 'item6'); INSERT INTO item (parent_id, name) VALUES (6, 'item7'); INSERT INTO item (parent_id, name) VALUES (null, 'item8'); CREATE TABLE IF NOT EXISTS user_item ( id int(11) NOT NULL AUTO_INCREMENT, user_id INT, item_id INT, type varchar(16) NOT NULL, PRIMARY KEY(id), FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (item_id) REFERENCES item(id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO user_item (user_id, item_id, type) VALUES (1, 1, 'allow'); INSERT INTO user_item (user_id, item_id, type) VALUES (1, 3, 'deny'); INSERT INTO user_item (user_id, item_id, type) VALUES (1, 7, 'allow'); user_itemのuser_idが1のitemの行を取得したいのですが、 その条件として ・user_itemテーブルのtypeが'allow'のitem_id以下のitemの行 ・ただしtypeが'deny'のitem_id以下の行は除く この例だと、user_itemの INSERT INTO user_item (user_id, item_id, type) VALUES (1, 1, 'allow'); の行によってitemテーブルの INSERT INTO item (parent_id, name) VALUES (null, 'item1'); INSERT INTO item (parent_id, name) VALUES (1, 'item2'); INSERT INTO item (parent_id, name) VALUES (2, 'item3'); INSERT INTO item (parent_id, name) VALUES (3, 'item4'); INSERT INTO item (parent_id, name) VALUES (2, 'item5'); が取得候補になりますが、 INSERT INTO user_item (user_id, item_id, type) VALUES (1, 3, 'deny'); によって INSERT INTO item (parent_id, name) VALUES (2, 'item3'); INSERT INTO item (parent_id, name) VALUES (3, 'item4'); の行は除かれ、 INSERT INTO item (parent_id, name) VALUES (null, 'item1'); INSERT INTO item (parent_id, name) VALUES (1, 'item2'); INSERT INTO item (parent_id, name) VALUES (2, 'item5'); の行が取得されます。 つまりitemテーブルにおいて上の階層の直近の(user_itemと結合して取得した)typeが 'allow'である場合のみ取得したいのです。 INSERT INTO item (parent_id, name) VALUES (null, 'item1');←取得 INSERT INTO item (parent_id, name) VALUES (1, 'item2');←取得 INSERT INTO item (parent_id, name) VALUES (2, 'item3'); INSERT INTO item (parent_id, name) VALUES (3, 'item4'); INSERT INTO item (parent_id, name) VALUES (2, 'item5');←取得 INSERT INTO item (parent_id, name) VALUES (null, 'item6'); INSERT INTO item (parent_id, name) VALUES (6, 'item7');←取得 INSERT INTO item (parent_id, name) VALUES (null, 'item8'); 複雑ではありますが、これはどのようなSQL文にすれば良いのでしょうか?

    • ベストアンサー
    • MySQL
  • 最初に挿入された行だけ取得したい

    このジャンルでお願いします。 次のようなテーブルで CREATE TABLE IF NOT EXISTS user ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(32) NOT NULL, PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO user (name) VALUES ('user1'); INSERT INTO user (name) VALUES ('user2'); INSERT INTO user (name) VALUES ('user3'); CREATE TABLE IF NOT EXISTS item ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(32) NOT NULL, PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO item (name) VALUES ('item1'); INSERT INTO item (name) VALUES ('item2'); INSERT INTO item (name) VALUES ('item3'); CREATE TABLE IF NOT EXISTS user_item ( id int(11) NOT NULL AUTO_INCREMENT, user_id INT, item_id INT, PRIMARY KEY(id), FOREIGN KEY (item_id) REFERENCES user(id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (user_id) REFERENCES item(id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO user_item (user_id, item_id) VALUES (1, 1); INSERT INTO user_item (user_id, item_id) VALUES (2, 1); INSERT INTO user_item (user_id, item_id) VALUES (3, 2); INSERT INTO user_item (user_id, item_id) VALUES (1, 2); INSERT INTO user_item (user_id, item_id) VALUES (1, 3); INSERT INTO user_item (user_id, item_id) VALUES (3, 3); user_itemテーブルでのselectで、 user_idが1で一番最初に挿入された行だけ を取得したいのですが、どのようなSQL文にすれば良いのでしょうか? この例なら INSERT INTO user_item (user_id, item_id) VALUES (1, 1);←取得 INSERT INTO user_item (user_id, item_id) VALUES (2, 1); INSERT INTO user_item (user_id, item_id) VALUES (3, 2); INSERT INTO user_item (user_id, item_id) VALUES (1, 2);←user_id=3が最初に挿入されているので取得しない INSERT INTO user_item (user_id, item_id) VALUES (1, 3);←取得 INSERT INTO user_item (user_id, item_id) VALUES (3, 3);

    • ベストアンサー
    • MySQL
  • 閉包テーブルのノードの移行について

    このジャンルでお願いします。 次のようなテーブルで CREATE TABLE IF NOT EXISTS item ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(32) NOT NULL, PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO item (name) VALUES ('item1'); INSERT INTO item (name) VALUES ('item2'); INSERT INTO item (name) VALUES ('item3'); INSERT INTO item (name) VALUES ('item4'); INSERT INTO item (name) VALUES ('item5'); INSERT INTO item (name) VALUES ('item6'); CREATE TABLE IF NOT EXISTS treepath ( ancestor_id int(11) NOT NULL, descendant_id int(11) NOT NULL, FOREIGN KEY (ancestor_id) REFERENCES item(id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (descendant_id) REFERENCES item(id) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(ancestor_id, descendant_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO treepath (ancestor_id, descendant_id) VALUES (1, 1); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (1, 2); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (1, 3); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (1, 4); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (1, 5); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (1, 6); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (2, 2); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (2, 4); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (2, 5); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (2, 6); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (3, 3); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (4, 4); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (4, 6); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (5, 5); INSERT INTO treepath (ancestor_id, descendant_id) VALUES (6, 6); item1┬item2    │ ├item4    │ │  └item6    │ └item5    │    └item3 を item1┬item2    │ │      │ └item5    │    └item3      └item4        └item6 のようにitem4以下のノードをitem3の下に移したいのですが、 その場合のtreepathテーブルの更新はどのようなSQL文にすれば良いのでしょうか?

    • ベストアンサー
    • MySQL
  • INSERT INTOに関しまして。

    $sql = "INSERT INTO テーブル名(name,day,kg)VALUES('','$day','-1')"; 現在このようなSQL文でINSERTしていますが、データベース内にあるカラムname全てに対してINSERTするにはどうすれば良いでしょうか??現在のSQL文ではそれができず、nameが空欄の状態で更新されてしまいます。

    • ベストアンサー
    • PHP
  • 指定された趣味を持つメンバーがいるグループを抽出するSQL

    グループテーブル、メンバーテーブル、趣味テーブルの3つのテーブルがあります。 あるメンバーはあるグループに属しており、趣味を1つ持っています。 以下がそのSQLです。 CREATE TABLE groups ( g_id int primary key ); CREATE TABLE members ( m_id int primary key , g_id int , h_id int ); CREATE TABLE hobbies ( h_id int primary key, h_name text ); INSERT INTO groups VALUES ( 1 ); INSERT INTO groups VALUES ( 2 ); INSERT INTO groups VALUES ( 3 ); INSERT INTO members VALUES ( 1, 1, 1); INSERT INTO members VALUES ( 2, 1, 3); INSERT INTO members VALUES ( 3, 1, 4); INSERT INTO members VALUES ( 4, 1, 4); INSERT INTO members VALUES ( 5, 2, 1); INSERT INTO members VALUES ( 6, 2, 2); INSERT INTO members VALUES ( 7, 2, 3); INSERT INTO members VALUES ( 8, 3, 2); INSERT INTO members VALUES ( 9, 3, 3); INSERT INTO members VALUES ( 10, 3, 4); INSERT INTO hobbies VALUES ( 1, 'sports' ); INSERT INTO hobbies VALUES ( 2, 'music' ); INSERT INTO hobbies VALUES ( 3, 'book' ); INSERT INTO hobbies VALUES ( 4, 'drive' ); 指定された趣味を持つメンバーがいるグループを抽出するにはどうすればいいでしょうか? 例えば、「読書が趣味なメンバーとドライブが趣味なメンバーがいるグループは?」「グループ1とグループ3」のような感じです。 一応自分で考えてみたのが、以下ですが、これだと趣味の指定が増減すると大きくSQLが変わってしまいます。 もっといいやり方はないでしょうか? 私はPostgreSQL8を使ってますが、汎用的なSQLであれば、そっちの方がいいです。 SELECT distinct m.g_id FROM members m join hobbies h ON m.h_id = h.h_id where h.h_name = 'drive' INTERSECT SELECT distinct m.g_id FROM members m join hobbies h ON m.h_id = h.h_id where h.h_name = 'book';

  • 【SQL文】Insert into文で文法エラー

    insert into文で思ったような結果がでません。SQL文にお詳しい方、ご教授いただけますでしょうか? SQLは初心者レベルです。 期待している結果: テーブルT-BBSにT-USRのusr-id全リストを入れて、T-BBSのa,b,cには固定の数値を入れたいと思っています。 テーブル例: テーブル名:T-BBS ,カラム:usr-id,a,b,c, テーブル名:T-USR, カラム:usr-id 結果 user-id | a | b | c 2 |1 | 2 | 3 3 |1 | 2 | 3 4 |1 | 2 | 3 7 |1 | 2 | 3 私が考えたSQL文ですが、 INSERT INTO T-BBS(SELECT user-id FROM T-USR,1,2,3) →×(文法エラー) INSERT INTO T-BBS(user-id,a,b,c) VALUES (SELECT user-id FROM T-USR,1,2,3)→× 文法エラー INSERT INTO T-BBS(user-id,a,b,c) VALUES ((SELECT user-id FROM T-USR),1,2,3)→×サブクエリが複数行を含んでいる ちなみにデータベースはH2 Databaseというものみたいですが、mySQLと方言は同じという認識をもってます。 以上宜しくお願いします。

    • ベストアンサー
    • MySQL
  • PL/SQLでREPRACE INTO構文と同様の処理を作成

    PL/SQLでREPRACE INTO構文と同様の処理を作成 別のテーブルにレコードを投入する処理を実行するトリガを作成したのですが、 プライマリ・キーが重複するレコードの投入時に、一意制約でエラーになってしまいます。 トリガの作為としましては、プライマリキーが重複する際には上書きさせたいのですが、この場合、PLSQLではどのようなコマンドがあるのでしょうか? (mySQLのREPLACE INTO と同様の処理を行うコマンドを想定しています) ↓下記のINSERT INO の箇所をREPLACE INTOと同様の処理を行うコマンドにしたいと思っております CREATE OR REPLACE TRIGGER TRI_TEST after update of TRI_NAME ,TRI_CALLED on cp_MV_TABLE FOR EACH ROW begin if (:old.TRI_NAME != :new.TRI_NAME or :old.TRI_CALLED != :new.TRI_CALLED ) THEN INSERT INTO TR_RUS_TABLE ( TRI_NO , TRI_DATE , TRI_NAME , TRI_CALLED ) values ( :new.TRI_NO , :new.TRI_DATE , :new.TRI_NAME , :new.TRI_CALLED ); end if; end; /

  • IDENTITY列の複数テーブルへのINSERT

    テーブルAへINSERTをした場合のIDENTITY列の値を 同じトランザクション内で テーブルBの別のフィールドへINSERTしたいのですが、 どのようにSQLを書けばよいのか、困っています。 どうか、ご教示お願い致します。 INSERT INTOTABLE_A (NAME_A) VALUES ('あいうえお') ↓ INSERT INTOTABLE_A (A_ID,NAME_B) VALUES (取得したA_ID, 'さしす') INSERT INTOTABLE_A (NAME_A) VALUES ('かきくけこ') ↓ INSERT INTOTABLE_A (A_ID,NAME_B) VALUES (取得したA_ID, 'たちつ') INSERT INTOTABLE_A (NAME_A) VALUES ('さしすせそ') ↓ INSERT INTOTABLE_A (A_ID,NAME_B) VALUES (取得したA_ID, 'なにぬ') TABLE_A ID NAME_A 5  'あいうえお' 6  'かきくけこ' 7  'さしすせそ' TABLE_B ID A_ID NAME_B 1  5  'さしす' 2  6  'たちつ' 3  7  'なにぬ'

  • データベースに変数の値を挿入

     HTMLのフォームから、getParameterで取得した値(id,name,club)をデータベースに挿入したいのですが、 String sql="insert into test_table values(id,name,club)";  と記述してもその文字列がそのままテーブルに反映されてしまいます。  もちろん、 String sql="insert into test_table values('12','●田○郎','野球部')"; とあらかじめ記述しておけばこのデータがテーブルに挿入されるのですが・・・。  PHPでは確かvalues('{$id}','{$name}','{$club}')のように記述すればできたので戸惑っています。  JAVAでSQL文に変数を含める場合、どのように記述すればいいのでしょうか?

    • ベストアンサー
    • Java
  • MySQLで漢字を登録したい。

    MySQLで漢字を登録したい。 insert into personal(id, old, name) values(1, 18, 'Satou'); とやればうまくいくのですが、 insert into personal(id, old, name) values(1, 18, '佐藤'); とやっても????となってしまいます。 どのようにすればいいでしょうか。

    • ベストアンサー
    • MySQL

専門家に質問してみよう