(速度はおいておいて、論理条件だけみたら)parents.deleted_at IS NULL OR children.deleted_at IS NULL で検索したかった話なのかな?
parents側の論理削除はここでは無関係だね。LEFT JOINする右側テーブルで論理削除されたレコードをないものとしたければ、JOIN時に条件つけろということ。
これハマったときあったなあ。理想的には論理削除なしがいいけど、仕方ないときはビュー作るかな。
そもそも、where句の書き方がおかしいだけ。性能はオプティマイザ次第だが論理削除で isnull を使う設計もおかしい。
WHERE句っていう文法の問題じゃなくて、子テーブルのフィルタリングとJOIN演算の適用順序を意識する必要がある、という話
個人的には、論理削除のように、毎回必ず同じwhere条件をつけるものは、テーブルを分けるように設計してる。アーキテクトとしては、いつか誰かがやらかす可能性のある設計はできるだけ潰しておきたいところ。
具体的なケースの具体的なクエリが無いのでアレだが、where 区でもnot exists ちゃんと書けば済む話では? 論理削除チェックにnull使ってるのも原因か。普通にflagならこんなややこしいことにならない。
not existsを使うようになって減ったけど、よくやる。よくSQL書いてるときは問題ないんだけど、書いてないと忘れる。
LeftJoinだと親があって子がないレコードは見えるけど論理削除した子供を持った親は見えない、という話か。Join条件はできる限りJoinに書く派なのであえて意識したことはなかったな。
IS NULLでしか論理削除が判定できない データベースの設計がおかしいのでは?
Viewを使えみたいな話かと思ったら、そもそも論理削除に限った話じゃなかった。
論理削除は窓から捨てろ。話はそれからだ
そりゃ、LEFT JOINなのにchildrenテーブルをparentsの抽出条件に入れちゃダメ、という話なのでは。「不具合」というより仕様というか。「親テーブルの絞り込みはWHERE句で大丈夫です」
Gemini"「初学者向け:SQLの評価順序におけるハマりどころ」として書き直すべき内容ですね" と言う感じで社内向けには良い注意喚起だけど公開する内容としては技術ブランディング的にマイナスではと心配に…他人事ながら
みんなだいすきゴミ箱機能。
参照以外の作業をする場合、left join 使うのがおかしい
どういう場合に子要素が全部削除されてないのに、親要素に削除フラグ立てるのかの利用ケースが思い浮かばない。 子要素がすべて削除もしくは子要素が0の場合削除フラグ立てるのはあり得るけど。
nullは不定値だ。論理削除はしてるかしてないかなんだからtrue/falseか1/0で判断しろ
子テーブルに削除フラグ付けるの正しいの??
ON句で絞り込みをしないでください。ON句はテーブルの接続を表すために使います。 この場合はサブクエリを使うとかですね。というか、消えているはずのデータならビュー作っておけば良くない?
なんか当たり前です、みたいに書いてあるけど違和感あんなぁと思ってコメ見て納得。
“つまり、子テーブルの論理削除の絞り込みはJOIN句で書いてください。(慣習的にそうしていた人も多いはず)”
NULLに意味をもたすな馬鹿たれ、と言う話かと思った。
ViewとかCTE内で除外してからJoinするとバッチリ安全なので、指導するならそっちじゃない?/削除日付が入っていない事だけが判定基準の論理削除ルールってあまりお勧めしない。何故ならインデックス組みにくいから…。
どうでもいいけど"具体的にこんなケースで不具合が"の予約がない商品の抽出ならnot exists使うべきだと思うよ。あと削除日時でチェックせず削除フラグを設けた方が良いよ。
JOIN使ってる時点でアウト
最初にグルーピングでユニークIDを絞った集合のID群を削除するようにした方がええと思うで
フラグ版だとWHERE (略) AND (children.delete_flag = 0 OR children.id IS NULL)な感じだろうけど同じ結果になるからNULLの問題じゃない / WHEREサブクエリは無謀 / FROMサブクエリ、CTE、VIEWはON絞り込みと大差ない(好みの問題でしかない)
WHERE句はダメにゃ!ボクが優しく教えてあげるにゃ!
JOIN結果が想像できてないだけでは?最適化がどこまで効くかにもよるけどWITHとかでテーブル細かく作っていけば抜け漏れなく想像しやすくなるよ。たぶん。
理解不能
いろいろ間違ってて草
そもそも親を取りたいのに LEFT JOIN した子を抽出条件にするのが実装ミスくさいってことね。
サブクエリー使う方が自然では。 select * from children where deleted_at is null と left join しろ / " 参照以外の作業をする場合、left join 使うのがおかしい" は何が言いたいのか意味が分からん
主張はわかるけど、評価順とかそういう込み入った話では無い気が。最初のクエリは parent and child になってるんだからそりゃそうだよね感が。
IS NULLってインデックス効かないんじゃなかった?と思ったらちゃんと効くらしい
そもそも論理削除が有り得ない。論理削除のような機能が必要で1つのテーブルで実現するなら、きちんとした業務的な名前が付いた列で表現して普通にWHERE句だろ。シンプルにしておけよ。
ベスト→論理削除フラグ使わない、ベター→ビューを作って常にそれを使う、だと思ってる。
その昔、Oracleでは外部結合を(+)って書いてた時期があってぇ
DB
要件変わっとるやんけ。ただのバグだろ
論理削除の判定をNULLでやってる仕様がマズい。
何言ってんだこいつ
論理削除フラグはNOT NULL定義にするのが基本。カーディナリティが低いとインデックス使わないからこの辺は要検討
検索結果件数どうすんの。"予約取り消しが論理削除で実装されていた場合、この商品は予約が1件も入っていないのにもかかわらず抽出対象から外れてしまいます"商品検索なのか予約検索なのか仕様がおかしいだけだろ。
ぶっ叩かれてるの、いいね。/こういう時は当事者意識を薄めて、反応の中からスキルアップにつながりそうな文面だけ受け取るのが吉
結合したあとでwhere適用するから実質INNER JOINになるって話かな。たしかにややこい
論理削除は関係ないような?部署一覧と所属する65才以上の社員一覧、みたいな問いあわせでも同じで、一般的な結合と絞り込みの問題では。
ブコメ大半はちゃんと理解されていないなあ。あるあるある。
ソフトデリートにタイムスタンプを入れる系は、 ただのフラグだとユニークが死ぬからだろうな…
タイトルが悪い。
普通はVIEW作るんじゃないの?そんでselectに書かなきゃ問題ないよね。。。
JOINに書くのは結合条件で、WHEREに書くのはデータ全体の取得条件。今回の場合、論理削除された子テーブルをJOIN対象から外すだけの時は結合条件、紐づく親データも対象から外すなら取得条件になる。後者はLEFT JOINと矛盾
ブクマがメチャクチャ割れていて定見がないのがわかる。絶対使うものなんだからDBがシステムとして実装しなよ。
期待する振る舞いのテストを書くようにすればいいんじゃないかな
SQLの評価順を理解していないと間違えるよ、というだけで論理削除は関係ないのでは。WHERE とJOINどちらの例が正しいかは仕様によるし一般化できる話でもないような
WHERE使っとるやん、日本語おかしいやろ
WHERE句以前に、情報技術から言って、親テーブル側で判定したら包含関係が適切じゃない。写像して全件マッチしたら処理が遅くなるに決まってる。それが分からない人は数学から勉強したほうがいい
元記事は言葉の定義がごちゃってるし、そもそものクエリがおかしい。トプコメのようにテーブルを分ける設計が良さそう。その時、削除時に別テーブルへinsertさせるのをアプリ側でやるかDBトリガーを使うかは要件次第か
論理削除の絞り込みはWHERE句でやるな
(速度はおいておいて、論理条件だけみたら)parents.deleted_at IS NULL OR children.deleted_at IS NULL で検索したかった話なのかな?
parents側の論理削除はここでは無関係だね。LEFT JOINする右側テーブルで論理削除されたレコードをないものとしたければ、JOIN時に条件つけろということ。
これハマったときあったなあ。理想的には論理削除なしがいいけど、仕方ないときはビュー作るかな。
そもそも、where句の書き方がおかしいだけ。性能はオプティマイザ次第だが論理削除で isnull を使う設計もおかしい。
WHERE句っていう文法の問題じゃなくて、子テーブルのフィルタリングとJOIN演算の適用順序を意識する必要がある、という話
個人的には、論理削除のように、毎回必ず同じwhere条件をつけるものは、テーブルを分けるように設計してる。アーキテクトとしては、いつか誰かがやらかす可能性のある設計はできるだけ潰しておきたいところ。
具体的なケースの具体的なクエリが無いのでアレだが、where 区でもnot exists ちゃんと書けば済む話では? 論理削除チェックにnull使ってるのも原因か。普通にflagならこんなややこしいことにならない。
not existsを使うようになって減ったけど、よくやる。よくSQL書いてるときは問題ないんだけど、書いてないと忘れる。
LeftJoinだと親があって子がないレコードは見えるけど論理削除した子供を持った親は見えない、という話か。Join条件はできる限りJoinに書く派なのであえて意識したことはなかったな。
IS NULLでしか論理削除が判定できない データベースの設計がおかしいのでは?
Viewを使えみたいな話かと思ったら、そもそも論理削除に限った話じゃなかった。
論理削除は窓から捨てろ。話はそれからだ
そりゃ、LEFT JOINなのにchildrenテーブルをparentsの抽出条件に入れちゃダメ、という話なのでは。「不具合」というより仕様というか。「親テーブルの絞り込みはWHERE句で大丈夫です」
Gemini"「初学者向け:SQLの評価順序におけるハマりどころ」として書き直すべき内容ですね" と言う感じで社内向けには良い注意喚起だけど公開する内容としては技術ブランディング的にマイナスではと心配に…他人事ながら
みんなだいすきゴミ箱機能。
参照以外の作業をする場合、left join 使うのがおかしい
どういう場合に子要素が全部削除されてないのに、親要素に削除フラグ立てるのかの利用ケースが思い浮かばない。 子要素がすべて削除もしくは子要素が0の場合削除フラグ立てるのはあり得るけど。
nullは不定値だ。論理削除はしてるかしてないかなんだからtrue/falseか1/0で判断しろ
子テーブルに削除フラグ付けるの正しいの??
ON句で絞り込みをしないでください。ON句はテーブルの接続を表すために使います。 この場合はサブクエリを使うとかですね。というか、消えているはずのデータならビュー作っておけば良くない?
なんか当たり前です、みたいに書いてあるけど違和感あんなぁと思ってコメ見て納得。
“つまり、子テーブルの論理削除の絞り込みはJOIN句で書いてください。(慣習的にそうしていた人も多いはず)”
NULLに意味をもたすな馬鹿たれ、と言う話かと思った。
ViewとかCTE内で除外してからJoinするとバッチリ安全なので、指導するならそっちじゃない?/削除日付が入っていない事だけが判定基準の論理削除ルールってあまりお勧めしない。何故ならインデックス組みにくいから…。
どうでもいいけど"具体的にこんなケースで不具合が"の予約がない商品の抽出ならnot exists使うべきだと思うよ。あと削除日時でチェックせず削除フラグを設けた方が良いよ。
JOIN使ってる時点でアウト
最初にグルーピングでユニークIDを絞った集合のID群を削除するようにした方がええと思うで
フラグ版だとWHERE (略) AND (children.delete_flag = 0 OR children.id IS NULL)な感じだろうけど同じ結果になるからNULLの問題じゃない / WHEREサブクエリは無謀 / FROMサブクエリ、CTE、VIEWはON絞り込みと大差ない(好みの問題でしかない)
WHERE句はダメにゃ!ボクが優しく教えてあげるにゃ!
JOIN結果が想像できてないだけでは?最適化がどこまで効くかにもよるけどWITHとかでテーブル細かく作っていけば抜け漏れなく想像しやすくなるよ。たぶん。
理解不能
いろいろ間違ってて草
そもそも親を取りたいのに LEFT JOIN した子を抽出条件にするのが実装ミスくさいってことね。
サブクエリー使う方が自然では。 select * from children where deleted_at is null と left join しろ / " 参照以外の作業をする場合、left join 使うのがおかしい" は何が言いたいのか意味が分からん
主張はわかるけど、評価順とかそういう込み入った話では無い気が。最初のクエリは parent and child になってるんだからそりゃそうだよね感が。
IS NULLってインデックス効かないんじゃなかった?と思ったらちゃんと効くらしい
そもそも論理削除が有り得ない。論理削除のような機能が必要で1つのテーブルで実現するなら、きちんとした業務的な名前が付いた列で表現して普通にWHERE句だろ。シンプルにしておけよ。
ベスト→論理削除フラグ使わない、ベター→ビューを作って常にそれを使う、だと思ってる。
その昔、Oracleでは外部結合を(+)って書いてた時期があってぇ
DB
要件変わっとるやんけ。ただのバグだろ
論理削除の判定をNULLでやってる仕様がマズい。
何言ってんだこいつ
論理削除フラグはNOT NULL定義にするのが基本。カーディナリティが低いとインデックス使わないからこの辺は要検討
検索結果件数どうすんの。"予約取り消しが論理削除で実装されていた場合、この商品は予約が1件も入っていないのにもかかわらず抽出対象から外れてしまいます"商品検索なのか予約検索なのか仕様がおかしいだけだろ。
ぶっ叩かれてるの、いいね。/こういう時は当事者意識を薄めて、反応の中からスキルアップにつながりそうな文面だけ受け取るのが吉
結合したあとでwhere適用するから実質INNER JOINになるって話かな。たしかにややこい
論理削除は関係ないような?部署一覧と所属する65才以上の社員一覧、みたいな問いあわせでも同じで、一般的な結合と絞り込みの問題では。
ブコメ大半はちゃんと理解されていないなあ。あるあるある。
ソフトデリートにタイムスタンプを入れる系は、 ただのフラグだとユニークが死ぬからだろうな…
タイトルが悪い。
普通はVIEW作るんじゃないの?そんでselectに書かなきゃ問題ないよね。。。
JOINに書くのは結合条件で、WHEREに書くのはデータ全体の取得条件。今回の場合、論理削除された子テーブルをJOIN対象から外すだけの時は結合条件、紐づく親データも対象から外すなら取得条件になる。後者はLEFT JOINと矛盾
ブクマがメチャクチャ割れていて定見がないのがわかる。絶対使うものなんだからDBがシステムとして実装しなよ。
期待する振る舞いのテストを書くようにすればいいんじゃないかな
SQLの評価順を理解していないと間違えるよ、というだけで論理削除は関係ないのでは。WHERE とJOINどちらの例が正しいかは仕様によるし一般化できる話でもないような
WHERE使っとるやん、日本語おかしいやろ
WHERE句以前に、情報技術から言って、親テーブル側で判定したら包含関係が適切じゃない。写像して全件マッチしたら処理が遅くなるに決まってる。それが分からない人は数学から勉強したほうがいい
元記事は言葉の定義がごちゃってるし、そもそものクエリがおかしい。トプコメのようにテーブルを分ける設計が良さそう。その時、削除時に別テーブルへinsertさせるのをアプリ側でやるかDBトリガーを使うかは要件次第か