2011-12-15 12 views
7

私は3つのテーブルを持っています:歯科医、グループ、およびグループリンク。多くの歯科医は、groupdentlinkテーブルを通じて多くのグループにリンクしています。プライマリキーなしの挿入先

だから私はそれがgroupdentlink(状態のすべての歯科医を状態のすべてのグループとリンクする)に行を挿入するクエリを作成しようとしているが、それらの行がまだ存在しない場合にのみ。一言で言えば、既存のものを上書きしたり、それらを複製したりせずに新しい行を追加したいのです。

だから、クエリの意図のようなものです:

INSERT INTO groupdentlink (f_dent_id, f_group_id, f_schedule_id) 
VALUES ('$_POST[id]', '$groupid', '$scheduleid') 
WHERE NOT EXISTS ('$_POST[id]', '$groupid') 

そして私はgroupdentlinkテーブル内の任意の主キーを持っていません。

ありがとうございます!

答えて

18

あなたが本当にあなた自身の(作業)クエリを記述したい場合は...


INSERT INTO groupdentlink (
    f_dent_id, f_group_id, f_schedule_id 
) SELECT 
    '$_POST[id]' f_dent_id, 
    '$groupid' f_group_id, 
    '$scheduleid' f_schedule_id 
FROM DUAL 
WHERE NOT EXISTS (
    SELECT 1 
    FROM `groupdentlink` 
    WHERE 
    f_dent_id = '$_POST[id]' AND f_group_id = '$groupid' 
    LIMIT 1 -- will stop mysql to stop searching after first match 
) 

...しかし、MySQLはあなたのためのすべてのこれを扱うことができます!


あなたは2列の結合セットにUNIQUEキー制約を追加する必要があり、MySQLがあなたのためにこれを処理するために主キーを必要としません。

dent_group_uniq_keygroupdentlinkという固有のキーを追加するクエリ。

ALTER TABLE groupdentlink ADD UNIQUE KEY `dent_group_uniq_key` (
    f_dent_id, f_group_id 
); 

その後、あなたのクエリにINSERT IGNOREを使用します。

INSERT IGNORE INTO groupdentlink (
    f_dent_id, f_group_id, f_schedule_id 
) VALUES (
    '$_POST[id]', '$groupid', '$scheduleid' 
) 

INSERT IGNOREそれがキー制約のために失敗した場合、それは何も起こるように動作します、あなたのテーブルに行を挿入しようとします。

+0

外部キー制約違反のようなさまざまな理由で失敗した場合、エラーは発生しません。 – greyfairer

+0

@greyfairer重複したキーのために挿入が失敗した場合にのみ、 "無視"します。外部キーの制約が引き続き適用されます。 –

+0

ありがとうございます。私は2番目の方法を使用しています。 –

2

あなたはほとんどそれを持っています! selectステートメントを使用すると、insertステートメントを入力できます。

INSERT INTO groupdentlink (f_dent_id, f_group_id, f_schedule_id) 
SELECT '$_POST[id]', '$groupid', '$scheduleid' 
WHERE 
    NOT EXISTS (
    select 
     1 
    from 
     groupdentlink 
    where 
     f_dent_id = $_POST[id] 
     and f_group_id = '$groupid' 
    ) 
+0

hmm。ここに私のクエリです:「groupdentlink。INSERT INTO(f_dent_id、f_group_id、f_schedule_id) \t SELECT '$ _POST [ID]'、 '$のrowv [ID]'、 '$行が[f_sched_id]'( \tがEXISTS、NOT \t \t f_dent_id = '$ _POST [ID]' groupdentlink から1を選択し、f_group_idは=「 を '$ groupidを' ...と私はあなたが句が存在するのクロージング括弧が必要 –

+0

構文エラーを取得しています。 – Eric

+0

...固定されています。まだ動作していません。Oy :( –

4
INSERT INTO groupdentlink (f_dent_id, f_group_id, f_schedule_id) 
SELECT '$_POST[id]', '$groupid', '$scheduleid' FROM dual 
WHERE NOT EXISTS (
    select * from groupdentlink 
    where f_dent_id='$_POST[id]' 
    and f_group_id='$groupid' 
) 

をそして私はあなただけを確認するために組み合わせ(f_dent_id、f_group_id)上に複合主キーを作成することができると思います。ただ、これを行います。

+0

ヒントとして、 'exists'文で' * 'の代わりに' 1'を使用して、メモリー内の大きな列セットを取り戻そうとしていないようにしてください。クエリを少しスピードアップします(クエリが大きくなるほど大きな影響を与えることができ、エンジンに依存します)。 – Eric

+0

@エリック、それはそうではありません。 [Docs](http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html)を参照してください。伝統的に、EXISTSサブクエリはSELECT *で始まりますが、 SELECT 5またはSELECT column1などで始まります。このような副問い合わせでは、MySQLはSELECTリストを無視するため、違いはありません。 –

+0

ああ、MySQLはそれをしません。古いバージョンのSQL Serverはこれまでどおりに動作しているかどうかわかりませんが、それがすべての作業が完了した場所です。私はこれをベストプラクティスとして使用しています。 – Eric

1
INSERT INTO groupdentlink (f_dent_id, f_group_id, f_schedule_id) 
VALUES ('$_POST[id]', '$groupid', '$scheduleid') 
WHERE NOT EXISTS (
    select * from groupdentlink 
    where f_dent_id='$_POST[id]' 
    and f_group_id='$groupid' 
) 

(f_dent_id、f_group_id)の組み合わせで複合主キーを作成できると思います。

関連する問題