我无法解决这个SQL难题,我差不多想出来但最后一部分有点挑战。
我有一个广告系列表和一个用户表
广告系列的状态为:有效/无效。
最重要的是,广告系列和用户之间有一个联接表: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步:(和)并非专门分配给任何人:
SELECT campaigns.*
FROM campaigns
WHERE campaigns.status = 'active'
WHERE NOT EXISTS(select * FROM campaign_users WHERE campaign_users.campaign_id = campaigns.id)
output:
campaign: 1
第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
最后一步:
这是我被卡住的部分。
查询将所有“方面”组合在一起:只有非独占的活动广告系列(不分配给任何人)并且对于传入的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)
答案 0 :(得分:1)
You can use a simple trick: outer join all campaign_users
to the campaigns
. You'll get a row per campaign and user for exclusive campaigns and a row with user null for non-exclusive campaigns. Keep all campaigns for either the user in question (say user 1) or all users (user null).
select c.*
from campaigns c
left join campaign_users cu on cu.campaign_id = c.id
where c. status = 'active' and (cu.user_id = 1 or cu.user_id is null);
答案 1 :(得分:0)
You can UNION
the queries for Step 2 and 3 to get the required result, e.g.:
SELECT campaign_id
FROM campaigns
WHERE campaigns.status = 'active'
WHERE NOT EXISTS(select * FROM campaign_users WHERE campaign_users.campaign_id = campaigns.id)
UNION
SELECT campaign_id
FROM campaigns
WHERE campaigns.status = 'active'
INNER JOIN campaign_users ON campaign_users.campaign_id = campaigns.id
AND campaign_users.user_id = ?