私はこのSQLパズルを解決しようとしています。私はほとんどそれを理解しましたが、最後の部分はちょっと難しいです。 結合を結合して結合テーブルに存在
は私が持っているキャンペーンのテーブルとユーザーテーブルキャンペーンのステータスを持っている:非アクティブ/アクティブ。
さらに、キャンペーンとユーザーの間にjoinテーブルがあります:campaign_users。この表は、一部のユーザーにキャンペーンを排他的に割り当てるために使用されます。私はいくつかの「面」を組み合わせたクエリを作りたい
Campaigns
id name status
1 campaign_a active
2 campaign_b active
3 campaign_c active
4 campaign_d inactive
Users
id name
1 user_a
2 user_b
3 user_c
Campaign_users
id campaign_id user_id
1 2 1
2 3 2
3 4 1
:
は、このデータを考えます。
ステップ1:私は最後の部分にこだわって言ったように、ここで私のステップで選択してアクティブなキャンペーン:
SELECT campaigns.*
FROM campaigns
WHERE campaigns.status = 'active'
output
campaign: 1,2,3
ステップ2:(と)排他的に誰にも割り当てられていません。
ステップ3:(と)は、排他的にpassed_in USER_ID(1)に割り当てられています。
SELECT campaigns.*
FROM campaigns
WHERE campaigns.status = 'active'
INNER JOIN campaign_users ON campaign_users.campaign_id = campaigns.id
AND campaign_users.user_id = 1
output:
campaign: 2
最終ステップ:
は、これは私がこだわっている部分です。
all 'facets'をまとめて組み合わせるクエリ:排他的ではなく(誰にも割り当てられていない)、渡されたuser_id専用のアクティブなキャンペーンのみ。
これは少し矛盾しているように感じますが、内部結合は結合表に存在するキャンペーンのみを返しますが、 '非排他的'キャンペーンはスキップします。
expected output:
with passed_in user_id of 1
campaign: 1,2 (Active & non exclusive and exclusively assigned to user 2)
with passed_in user_id of 2
campaign: 1,3 (Active & non exclusive and exclusively assigned to user 2)
with passed_in user_id of 3
campaign: 3 (Active & non exclusive but no exclusive assigned to user 3)
あなたの問題は、必要がないときに参加することに起因します。あなたがする必要がないときに参加しないでください。条件は 'FROM' /' JOIN'節にない 'WHERE'節に属します。ユーザーのための排他的なキャンペーンを取得するには、通常、 'EXISTS'または' IN'節を使用します(疑似コード: "どこにユーザーのエントリが存在するか")。最終的なクエリは、2つの条件を「OR」:「存在しない(...)または存在する(...)」と組み合わせることになる。しかし、あなたの場合、より簡単なテクニックを使うことができます。私の答えを見てください。 –