【问题标题】:SQL Code to get results when there are no records in a table表中没有记录时获取结果的 SQL 代码
【发布时间】:2020-10-09 22:00:21
【问题描述】:

有 4 个表(用户、用户选项、选项类型 1 和选项类型 2)。此处不直接涉及用户表,但为了完整性而提及。以下是每个相关表的表列。

User Options:
    UserID,
    Option1ID,
    Option2ID,

Option1:
    Option1ID,
    Option1Description

Option2:
    Option2ID,
    Option2Description

选项 1 的所有值都可以与选项 2 的所有值组合,因此如果选项 1 值的数量为“x”,选项 2 值的数量为“y”,则选项组合的结果数量为“x”*“y” '。我想编写一个查询,即使在 UserOptions 表中没有该用户的 Option1ID 和 Option2ID 的特定组合的记录,它也总是会为给定的 UserID 生成 'x' * 'y' 行。此外,还应该有一列指示 Option1 和 Option2 的特定组合是否存在于 UserOptions 表中。

Option1
Option1ID   Option1Description
----------------------------------
1           1_Description1
2           1_Description2


Options2
Option2ID   Option2Description
----------------------------------
1           2_Description1
2           2_Description2


UserOptions
UserID  Option1ID   Option2ID
---------------------------------
1       1           2
1       2           2


Result
UserID  Option1ID   Option2ID   Exists
----------------------------------------------
1       1           1           0
1       1           2           1
1       2           1           0
1       2           2           1

鉴于上述情况,SQL 查询会是什么?另外请注意,UserID = 2 在 UsersOptions 表中不存在。在这种情况下,查询仍应返回 4 条记录,其中 UserID 列将始终为 2,OptionID 列将相同,Exists 列将始终为 0。

【问题讨论】:

  • 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入作为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出尽可能少的代码,即您显示的代码可以通过您显示的代码扩展为不正常的代码。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)的 SQL,并以表格式作为代码输入。 How to Ask 暂停整体目标的工作,将代码砍到第一个表达式,没有给出你期望的内容,说出你的期望和原因。
  • @philipxy 请注意,在您发表评论之前,我已经将 GMB 的回复标记为可接受的答案。
  • 这与我的评论无关。研究站点目标和协议。该网站的目的不是为提问者获得答案。 help centerMeta Stack OverflowMeta Stack Exchange
  • 您似乎还没有了解该网站。 PS 你的@ 不会通知 GMB 它的评论,因为他们不是这篇文章的评论者。 (您可以对他们的回答发表评论。)(@ 不需要。)请参阅 How do comment @replies work? 以学习使用 @x 通知一位非唯一非海报评论者 x 重新发表评论。 (海报和追随者会得到通知。)PS GMB 不断回答明显重复的问题,应该关闭。 PS 考虑在Meta Stack Overflow 发帖(研究后)。
  • @tdinpsp philpxy 不是版主(顺便说一句,我也不是;))而且绝对不是“巨魔”。他们只是想向您解释为什么您的问题可能会被关闭。在 SO 上,我们希望您向我们展示一些代码或您所做的工作。尽管 GMB 可以回答您的问题,但仍然建议避免提出没有代码行可显示的问题。另外请避免使用诸如“巨魔”之类的术语,因为它们与code of conduct 相悖。

标签: sql subquery left-join inner-join


【解决方案1】:

您可以cross join users 表与两个选项表生成所有可能的组合,然后在桥接表useroptions 中搜索与left join 匹配:

select u.userid, o1.option1id, o2.option2id, 
    case when uo.userid is null then 0 else 1 end as uo_exists
from users u
cross join option1 o1
cross join option2 o2
left join useroptions uo 
    on  uo.userid = u.id
    and uo.option1id = o1.option1id
    and uo.option2id = o1.option2id

您也可以使用exists 代替left join

select u.userid, o1.option1id, o2.option2id, 
    case when exists (
        select 1 
        from useroptions uo 
        where  uo.userid = u.id and uo.option1id = o1.option1id and uo.option2id = o1.option2iduo.userid
    ) then 1 else 0 end as uo_exists
from users u
cross join option1 o1
cross join option2 o2

【讨论】:

  • 有没有比另一种更有效的方法?
  • @tdinpsp:很难确定,您可能需要根据您的实际数据集进行评估。我会先尝试相关子查询,在 useroptions(userid, option1id, option2id) 上有一个索引。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多