从两个表中获取所有记录,但从第二个表中仅获取不在第一个

时间:2017-02-18 16:00:02

标签: mysql sql join

我正在创建一个MUD游戏。我有两个任务表,有一个active_quests和一个completed_quests。我的玩家可以看到很多自定义报告。

在一个这样的报告中,在他们选择了一堆quest_ids之后,我想向他们展示他们在该任务中的得分/状态。报告应该是这样的,我只想显示active_quests表中的分数(如果该表存在于该表中,或者来自completed_quests。

所以我需要的查询(伪代码)就像:

select active_quests.*
from active_quests
where quest_id in (<list_of_quest_ids>)
and player_id = <player_id>

UNION

select completed_quests.*
from completed_quests
where quest_id NOT in (<the_results_we_got_above>)
and quest_id in (<list_of_quests>)
and player_id = <player_id>

但我不知道如何写这个:(

3 个答案:

答案 0 :(得分:0)

假设你是一个像

这样的子选择
  select quest_id from you_quest_table where your_col = your_val

你可以使用像

这样的东西
    select active_quests.*
    from active_quests
    where quest_id in (
      select quest_id from you_quest_table where your_col = your_val
      )
    and player_id = <player_id>

    UNION

    select completed_quests.*
    from completed_quests
    where quest_id NOT in (

    select active_quests.*
    from active_quests
    where quest_id in (
      select quest_id from you_quest_table where your_col = your_val)
    and player_id = <player_id>

    )
    and quest_id in (
       select quest_id from you_quest_table where your_col = your_val
    )
    and player_id = <player_id>

答案 1 :(得分:0)

使用左外连接保留左表中的所有记录并匹配右表中的记录。

答案 2 :(得分:0)

一种方法使用not exists

select aq.*
from active_quests aq
where aq.quest_id in (<list_of_quest_ids>) and
      aq.player_id = <player_id>
union all
select cq.*
from completed_quests
where not exists (select 1
                  from activequests aq
                  where aq.player_id = cq.player_id and
                        aq.quest_id = cq.quest_id
                 )
      cq.quest_id in (<list_of_quests>) and
      cq.player_id = <player_id>;

注意:

  • 使用UNION ALL除非您明确要删除重复项(性能损失)。
  • 在MySQL中,如果使用关联逻辑,则无需在NOT EXISTS(或NOT INLEFT JOIN)逻辑中重复第一个查询。在其他数据库中,CTE会简化整个过程。
  • 通过适当的索引,这应该很快。