2016-09-13 4 views
-1

質問はRoRとして行われますが、クエリレベルについてはさらに多くの質問が当てはまります。すべての削除された関連付けを持つレコードのみを検索します

私はモデル

ModelA has_many ModelB 

を持っていると私はそれらの両方でparanoid宝石を使用しています。

私はModelBが関連付けられていないのいずれかまたはそのすべてModelBが(それゆえdeleted_atがNULLでない)削除されたすべてのModelAを見つけるためにしようとしています。

this questionに基づいて、私は望みの結果を得ることができましたが、クエリを読むことはそれがどのように動作しているかにはあまり意味がありません。

ModelA.joins('LEFT OUTER JOIN model_bs ON model_bs.model_a_id = model_as.id AND model_bs.deleted_at IS NULL') 
    .where('model_bs.model_a_id IS NULL') 
    .group(model_as.id) 

私が使用している結合条件も後でwhere節でnullになるため、このクエリを読むとわかりません。

誰かが適切に設定されたクエリを得るのを手伝ってもらえますか?これが適切な方法であれば、正しい結果が得られたクエリの仕組みを教えてください。

アップデート:私は何が起こっていたかを理解するために管理し、いくつかの生のSQLの後、以下のコメントで述べたように

。また、それを破壊(少なくとも私の観点から)それをより明確にするよう

を私のARソリューションを書いた:

このクエリは、独立して、左側にすべてのモデルを返し、通常の左外部結合を表し、右側に関連がある場合。他だけModelAで1行が返されます、関連するものがある場合

AND model_bs.deleted_at IS NULL

が利用可能ModelB属性を持つ行を返します。参加するには、余分な条件を追加する

ModelA.joins('LEFT OUTER JOIN model_bs ON model_bs.model_a_id = model_as.id') 

これらの行を適用すると、関連するモデルがない行だけが保持されます。

注:この場合 、動作します属性model_a_idまたはmodel_bの他の属性を使用しますが、この道を行けば、私は関連が存在する場合、そのは常にになるだろうという属性を使用してお勧めしますそこ。そうしないと、結果が間違ってしまう可能性があります。最後に

、私は私が欲しかったものを翻訳するために使用して終わってきたAR:

ModelA.joins('LEFT OUTER JOIN model_bs ON model_bs.model_a_id = model_as.id AND model_bs.deleted_at IS NULL') 
    .group('model_as.id') 
    .having('count(model_bs.id) = 0') 
+0

私も同様の問題がありました。この回答を確認することができます:http://stackoverflow.com/a/15660222/580346 – mrzasa

+0

ここに投稿した後、私は説明を探し続けました。 ARの代わりにraw SQLを少し使い、理由を理解するのを助けました。 – rpbaltazar

答えて

0

ねえ、あなたはPG

でそれを確認することができ、私は mysqlでそれをテストしているこの方法を試すことができます
ModelA.joins('LEFT OUTER JOIN model_bs ON model_bs.model_a_id = model_as.id') 
    .group('model_as.id') 
    .having('SUM(CASE WHEN model_bs.deleted_at IS NULL THEN 0 ELSE 1 END) AS OCT = 0') 
+0

私が以前に自分自身に答えたので、私の更新された答えを確認してください。 ジョインで条件をもう1つ追加するだけで、合理的な和を求めるのはなぜですか? これは行く方法ではないようです。 – rpbaltazar

+0

@rpbaltazarあなたの更新内容があなたの要件に合っていると確信していますか?私はそれがモデルを持っていないモデルAを返すと思います。すべてのモデルBを持っているあなたの 'modelA'は返されません.Bは削除されます。 –

+0

私はそれが働いていると確信しています。述語 'AND model_bs.deleted_at IS NULL'とのジョインの使用は私にそれを与えます。 'deleted_at' NULLとの関連付けがあれば、関連ごとに行が返されます。そうでなければ、関連付けなしで行が返されます。したがって、 'model_as.id'でグループ化すると、' model_bs.id'はそこにあり、1以上であるかどうかです。 – rpbaltazar

関連する問題