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

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

ただいまの
回答率

88.04%

[MySQL] サブクエリで挿入しようとすると、エラー(索引'PRIMARY'で重複しています)がでてしまう。

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,058

score 122

mst_staff.staffIdとリレーションのあるstaffIdと日付を主キーにしたmst_attendanceにselect文を使って、insert実行しようとしたら掲題のえらーがでました。
主キーが重複しているということだと思いますが、select文を確認しても日付とIdのどちらとも重複している行はありませんでした。
何が原因でどうすればよいのでしょうか。

テーブル作成時のSQL

CREATE TABLE `mst_attendance` (
 `date` date NOT NULL,
 `staffId` int(11) NOT NULL,
 `attend_time` time DEFAULT NULL,
 `leave_time` time DEFAULT NULL,
 `working_time` float DEFAULT NULL,
 `resting_time` float DEFAULT NULL,
 `overwork_time` float DEFAULT NULL,
 PRIMARY KEY (`date`,`staffId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

CREATE TABLE `mst_staff` (
 `staffId` varchar(6) NOT NULL,
 `password` varchar(20) NOT NULL,
 `staffName` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `authorityId` int(11) NOT NULL,
 `delete_flg` int(11) NOT NULL,
 PRIMARY KEY (`staffId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1


実行したSQL

INSERT INTO mst_attendance(
    date,
    staffId
)
SELECT CURRENT_DATE , ms.staffId
from mst_staff ms

発生したエラー

#1062 - '2019-05-20-0' は索引 'PRIMARY' で重複しています。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • coco_bauer

    2019/05/20 11:48

    「select文を確認しても」というのは、select文を実行して得られた結果と、`mst_attendance` テーブルの内容を、比較チェックしたという事ですか?
    エラーメッセージに出てくる '2019-05-20-0' という書式は Dateなんですか? Dateだと'2019-05-20'(yyyy-mm-dd形式)のような表現が普通だと思うのですが。

    キャンセル

  • maisumakun

    2019/05/20 11:55

    > エラーメッセージに出てくる '2019-05-20-0' という書式は Dateなんですか?

    複合インデックスをかけていると、`1つ目の値-2つ目の値`のような表記になりますので、これ自体は問題ないかと思います(2つ目が0なのが気にはなりますが)。

    キャンセル

回答 4

0

主キーが重複しているということだと思いますが、select文を確認しても日付とIdのどちらとも重複している行はありませんでした。

すでにmst_attendanceにある行と、mst_staffから挿入しようとした行が衝突した、ということではないかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

mst_staffのstaffIdカラムと当日=CURRENT_DATEの組み合わせがすでに
mst_attendanceに登録ずみのため競合しています

考え方として

  • insert ignore intoで新規データのときだけ挿入する
  • insert on duplicate key update構文で競合したときに上書きする

のどちらかの処理が必要です。
命題を見る限り投入するのが(date,staffId)の組み合わせだけなので
前者で十分でしょう

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

そのINSERTのSQLだと同じ日に複数回実行すると重複しますね。
存在するかどうかの有無をチェックするようにしてはどうでしょうか。

INSERT INTO mst_attendance(
 date, staffId
)
SELECT CURRENT_DATE , ms.staffId
from mst_staff ms
where not exists(
        select 1 from mst_attendance where date=CURRENT_DATE and staffId=ms.staffId
      )
;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

check解決した方法

-1

そもそもstaffIdはvarchar型でした。どうやらvarchar型をint型に入れようとしたために0へ自動変換されてそれが衝突したようです。
エラー文の'2019-05-20-0'はdateとstaffIdをつなげたものらしいです

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • MySQLに関する質問
  • [MySQL] サブクエリで挿入しようとすると、エラー(索引'PRIMARY'で重複しています)がでてしまう。