LoginSignup
2
2

More than 5 years have passed since last update.

[SQL] 冗長なクエリーはこちら

Posted at

この投稿の主旨

 自分が作成したクエリーとそれを手直ししてもらったクエリーを比較したとき、自分のクエリーがとても冗長だったもので、その戒めのためにもこの投稿をしましたorz..

 問題となったのは、親子関係のあるデータ構成があり、1回のクエリーで親と子の両方を取得したい場合がありました。プログラム上では親のデータは1回しか参照しないにも関わらず、親と子の両方を取得するクエリーで子のレコードに必ず親のデータもくっついてきて、データ量が肥大化してました。

実際のデータ構成と近い形で以下に記載します。

テーブル構成

  • 以下のテーブル構成で親子関係を表す
humansテーブル
id
name
human_relationsテーブル
parent_id
child_id

humans 1 - n human_relations

例)パパと子ども3人の場合

humans

id name
1 パパ
2 子ども1
3 子ども2
4 子ども3

human_relations

parent_id child_id
1 2
1 3
1 4

冗長なクエリーはこちら

// これだと子どものレコードに必ず親の情報がくっついてきて無駄になる

SELECT
parent.id as parent_id, parent.name as parent_name, child.id as child_id, child.name as child_name
FROM humans parent
LEFT JOIN human_relations hr ON parent.id = hr.parent_id 
LEFT JOIN humans child ON hr.child_id = child.id
WHERE parent.id = :id

結果

parent_id parent_name child_id child_name
1 パパ 1 子ども1
1 パパ 2 子ども2
1 パパ 3 子ども3

スマートなクエリーはこちら

// これだと親と子どもが分離されて余計なデータがなく取得できる

SELECT humans.id, humans.name
FROM humans LEFT JOIN human_relations hr ON humans.id = hr.child_template_id
WHERE (hr.parent_id = :id OR humans.id = :id)
AND humans.deleted IS NULL

結果

humans.id humans.name
1 パパ
2 子ども2
3 子ども3
4 子ども4
2
2
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
2
2