【问题标题】:How to replace a condition in left join through a where clause?如何通过 where 子句替换左连接中的条件?
【发布时间】:2020-02-06 11:24:06
【问题描述】:

尝试使用 where 子句而不是左连接来获得相同的结果

TableA 架构:

id
name
created_by

TableB 架构:

id 
name
updated_by

样本表A

id  name    created_by
1   pen      a
2   paste    k

样本表B

id  name        updated_by
1   inkpen      b
1   ballpen     c

left 加入查询

select tablea.id, tableb.id, tablea.name, tableb.name
from tablea
    left join tableb on tableb.id = tablea.id and tableb.updated_by = 'a'

结果

tablea.id       tableb.id       tablea.name     tableb.name
    1            NULL               pen           NULL

使用 where 子句查询:

select tablea.id, tableb.id, tablea.name, tableb.name
from tablea left join tableb
ON tableb.id = tablea.id WHERE tableb.updated_by = 'a'

结果

tablea.id       tableb.id       tablea.name     tableb.name
    NULL             NULL           NULL              NULL

我们在传递 user_id 之前使用了一个函数。 反过来,该函数返回一个表并在左连接中使用 user_id。 由于该函数没有使用索引,我们决定使用视图来代替。 但是,在视图中,我们不能传递变量。因此我们无法在 Left join 中使用 tableb.updated_by,因此在 where 子句中尝试了相同的查询。

我们如何编写查询,以便通过 where 子句获得与左连接相同的结果?

【问题讨论】:

  • WHERE 子句版本的语法无效。您使用的是哪个 dbms?

标签: mysql sql postgresql-9.4


【解决方案1】:

您的真实表格可能如下所示(主键粗体):

  • 项目(item_id、名称、created_by_user_id)
  • itemuserupdate(item_id、updated_by_user_id、名称)
  • 用户(user_id、姓名)

你可以做的是首先获取所有用户/项目组合,然后外部加入现有条目:

create myview as
select i.item_id, i.name, u.user_id, iu.name as name_by_user
  i.item_id,
  u.user_id,
from users u
cross join item i
left outer join itemuserupdate iu on iu.itemid = i.itemid
                                 and iu.updated_by_user_id = u.user_id;

然后您可以将此视图与

select item_id, name, name_by_user from myview where user_id = 123;

【讨论】:

  • itemuserupdate中,item_id不是主键
  • 好的。我假设该表中的每个项目和用户都有一个条目。但即使不是上述解决方案也应该有效。
【解决方案2】:

如何编写查询,以便通过 where 子句获得与左连接相同的结果?

你不能。

LEFT JOINON 子句中的条件未满足时,将第一个表的行与空值连接,替换第二个表中的一行。如果这些条件出现在WHERE 子句中,它们会在未满足时排除第一行。这有效地将您的LEFT JOIN 转换为普通的内部JOIN

【讨论】:

    猜你喜欢
    • 2015-05-02
    • 2012-05-01
    • 1970-01-01
    • 2017-07-04
    • 2011-02-25
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    相关资源
    最近更新 更多