LoginSignup
4
0

More than 1 year has passed since last update.

SQLでレコードをDELETEしてからINSERTする場合に気をつけること

Posted at

軽く自己紹介

初めまして!
Webのバックエンドエンジニアを志望して勉強している佐藤をいいます!
初記事なので、良くないところがいくつかあるかもです。
その時は指摘していただけると助かります!

実行環境

MacBook Air (M1, 2020)
macOS Monterey 12.4
PostgreSQL 13.7

発生した問題

SELECT * FROM テーブル名;でテーブルを表示する時に、idでソートされているわけではなく、削除したカラムの位置に新しいデータが挿入されることがある。

発生例

-- humanテーブル
-- SELECT * FROM human;
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  1 |  sato  |  17 | 2022-06-18 12:00:00.000000
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000

id 1のレコードを削除

-- DELETE FROM human WHERE id = 1;
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000    -- id 1のレコードが削除された!
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000

id 5, name sakuma, age 25の新しいデータを挿入する

-- INSERT INTO human (id, name, age) VALUES (5, sakuma, 25);
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  5 | sakuma |  25 | 2022-06-19 15:00:00.000000    -- 削除された一番上のカラムに挿入されている
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000

これは、SQLの仕様で、データの保存を効率よく行うために、書き込みの順序という概念がないとのこと。
僕は勝手にデータの保存は一番下のカラムにされるものなんだなって勘違いしてた...

解決策

ソートする時はORDER BYを使う

-- SELECT * FROM human ORDER BY id
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000
  5 | sakuma |  25 | 2022-06-19 15:00:00.000000

おお!綺麗にならんだ!

降順の場合は、ORDER BY カラム名 DESCを使う

-- SELECT * FROM human ORDER BY id DESC
 id |  name  | age | created_at
----+--------+-----+----------------------------------
  5 | sakuma |  25 | 2022-06-19 15:00:00.000000
  4 |  ito   |  22 | 2022-06-18 12:00:00.000000
  3 | suzuki |  19 | 2022-06-18 12:00:00.000000
  2 | tanaka |  20 | 2022-06-18 12:00:00.000000

逆になった!

まとめ

  • SELECT * FROM テーブル名;は昇順で表示されるわけではない
  • データの保存に順番という概念はない
  • 昇順にソートしたい時はORDER BYを使う
  • 逆に降順にソートしたい時はORDER BY カラム名 DESCを使う

参考にしたサイト

https://oshiete.goo.ne.jp/qa/1666055.html
2005年とだいぶ古い質問なのですが、調べてもこれくらいしか見つかりませんでした...
もし他に参考になるものなどあったら教えてください!

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0