質問: 1)を論理削除を行い、論理削除されていないデータをすべて取り出したいです。(つまり、id=3、4のみ取り出したいです。) ただ、論理削除された親レコードにに属している、子レコードは取り出さないようにしたいです。(id=2は id=1の子レコードのため取り出さないです。) つまり、id=1と2は取り出さず、id=3と4のみ取り出しく存じます。 どのような取り出し方を行えばよろしいでしょうか。 初歩的な質問となってしまい大変恐れ入りますが、ご回答頂けますと幸いでございます。 また、分かりづらい点などございましたら お気軽にご指摘頂けますと幸いでございます。 何卒どうぞよろしくお願い致します。
回答: 「親レコード(未削除のもの)を取得」と「子レコード(親レコードが未削除のもの)を取得)」を別々に行い、その結果を `UNION ALL` で結合すれば目的のものがとれると思います。 ``` -- 親レコード(未削除のもの)を取得 SELECT * FROM t_bbs WHERE parent_id IS NULL AND deleted_at IS NULL -- 結合 UNION ALL -- 子レコード(親レコードが未削除のもの)を取得) SELECT * FROM t_bbs AS child WHERE EXISTS ( SELECT * FROM t_bbs AS parent WHERE child.parent_id = parent.id AND parent.deleted_at IS NULL ) ``` ### 解説 #### 親レコード取得 * 親レコードを取得するほうは、ほぼ解説不要かと思います(取得条件に「親レコードであること(parent_idがNULLであること)」と「削除されていないこと(deleted_atがNULLであること)」を指定するだけ)。 #### 子レコード取得 * 子レコードを取得するほうは、EXISTSを使います(EXISTS=指定した条件のレコードが存在するか、を示すもの。詳細は「mysql exists」で検索すると、いろいろHITします)。 * 同じテーブルどうしをEXISTSするのですが、同じテーブル同士だと、カラムを指定するときに、どちらのテーブルを指すのかわからなくなるため、テーブルに、ASを使って別名をつけています(childとかparentというのは単なる別名です。役割をわかりやすくするためにこの名前にしましたが、別にaとかbでも動作上は問題ありません)。 追伸1: > > 初歩的な質問となってしまい大変恐れ入りますが、 > > > 一見簡単そうですが、こちら、あまり初歩的な内容ではないと思います。 追伸2: 取得する度に、こういう複雑なSQLを書かなくてはならなくなりますので(複雑なだけでなく実行速度も遅いです)、できれば、親レコードを削除する時に、子レコードについても削除するようにしたほうが良いと思います。