遭遇したエラー

1SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'modified' in field list is ambiguous

エラーメッセージの Integrity constraint violation は、 整合性規約違反 という意味です。

Column 'modified' in field list is ambiguous と続きますが、カラムの指定が曖昧なので、どう解釈していいかわからないよーという感じです。

やろうとしたこと

今回は UPDATE と JOIN の組み合わせがある SQL を実行した。

具体的には次のような SQL です。

1UPDATE `user_facilities` SET `level` = `level` + 1, `modified` = NOW()
2  LEFT JOIN `field_objects`
3    ON `user_facilities`.`field_object_id` = `field_objects`.`id`
4  WHERE
5    `field_objects`.`id` = ?
6   AND
7    `facility_id`.`id` = ?

マップ上の所有施設をレベルアップします。
ユーザはフィールド上に複数の拠点を所有することができるため、フィールド管理テーブルと JOIN しています。

うーん、あんまり良い例ではありませんでしたね。


レベルと同時に更新日時 (modified) を更新していますが、user_facilitiesfield_objects の両方に modified が定義されているため、どちらの modified を更新してよいかわからずエラーになっています。


これは

  • JOIN している複数テーブルに同じ名称のカラムがあり
  • かつどちらを見ればいいのかが不明瞭な場合

に「 Column ‘hoge’ in field list is ambiguous 」が発生します。

そのため、この例では UPDATE でしたが、 SELECT するフィールドでも、 WHERE 句の条件でも同様のエラーが発生することがありますよ。

対処方法

対処方法は「 JOIN しているうち、どのテーブルのカラムか 」を指示してあげれば OK です。

先の UPDATE では、ユーザ施設のレベルアップを行うものでした。

更新したいテーブルはレベルを管理する user_facilities であり、更新日時も user_facilities を変更すれば OK でした。

SQL の SET 句を細かく装飾すると、次となります。

1SET `user_facilities`.`level` = `user_facilities`.`level` + 1, `user_facilities`.`modified` = NOW()

理屈がわかれば、対処するのも難しくないと思います。