【问题标题】:Query to join tables where id matches and row exists查询以连接 id 匹配且行存在的表
【发布时间】:2014-04-09 07:12:14
【问题描述】:

我需要一个 MySQL 查询来连接多个表,前提是这些表具有匹配的 ID 并且它确实存在于表中。

我有 1 个父表和几个子表。父表包含每一行,而子表只包含他们需要的行。如果父表的 ID 存在于其中一个子表中,我需要将父表与子表连接起来。

这是我目前使用的,但不起作用。此查询最终没有结果,因为子表行可能不存在。例如,“widgets”表和“widget_login”表中可能存在 1 行,因为该小部件是“登录”小部件,但所有其他表都是空的。但它仍应检查所有表。我不确定如何克服这个问题。

SELECT FROM widgets
JOIN widget_login ON widget_login.id=widgets.id
JOIN widget_admin ON widget_admin.id=widgets.id
JOIN widget_facebook ON widget_facebook.id=widgets.id
WHERE widgets.type='specific_type'
etc...

【问题讨论】:

  • 如果您只需要所有子表中存在的匹配行,这将正常工作,否则如果您需要显示父表中的每一行,即使它们存在或不存在,请使用 LEFT OUTER JOIN子表
  • 是否有从子表中删除不存在的行?

标签: php mysql sql join


【解决方案1】:

去掉引号。并添加要选择的列,例如*.

SELECT * FROM widgets
INNER JOIN widget_login ON widget_login.id=widgets.id
INNER JOIN widget_admin ON widget_admin.id=widgets.id
INNER JOIN widget_facebook ON widget_facebook.id=widgets.id
WHERE ... etc etc

编辑:如果您只想从小部件中进行选择,请使用 EXISTS:

SELECT * FROM widgets
WHERE EXISTS (select * from widget_login where widget_login.id=widgets.id)
AND EXISTS (select * from widget_admin ON widget_admin.id=widgets.id)
AND EXISTS (select * from widget_facebook ON widget_facebook.id=widgets.id)
WHERE ... etc etc

或输入:

SELECT * FROM widgets
WHERE id IN (select id from widget_login)
AND id IN (select id from widget_admin)
AND id IN (select id from widget_facebook)
WHERE ... etc etc

顺便说一句:各个表的 ID 应该相等似乎很奇怪。表小部件中名为 ID 的列应标识小部件记录,而表 widget_login 中名为 ID 的列应标识登录记录。检查这个;也许你混淆了 ID。

编辑:再备注:如果您要查找至少存在于三个表之一中的小部件,请使用 EXISTS 或 IN 与 OR 而不是 AND。

编辑:要连接所有表并确保小部件存在于至少一个表中,请使用外部连接并检查结果是否为空:

SELECT * FROM widgets
LEFT JOIN widget_login ON widget_login.id=widgets.id
LEFT JOIN widget_admin ON widget_admin.id=widgets.id
LEFT JOIN widget_facebook ON widget_facebook.id=widgets.id
WHERE (widget_login.id IS NOT NULL OR widget_admin.id IS NOT NULL OR widget_facebook.id IS NOT NULL)
AND ... etc etc

请注意,其他表的列对于记录可以为空。例如。添加 AND widget_admin.name 'BAD' 将删除所有外部连接记录,因为 NULL 不是 'BAD'。

【讨论】:

  • 它需要包含子表中的数据。我不知道您提到的第二个或第三个查询是否会这样做。第一个查询没有结果,我不知道为什么。结果显示的唯一时间是当我使用左连接时,但是结果并不是我想要的 100%。我在其他 cmets 中提到了这些问题。感谢您的回复。
  • 所以我猜你想加入表格,但要确保其中至少有一个条目?我已经相应地编辑了我的答案。如果这仍然不是您想要的,请更详细地描述。
  • 图片胜于文字。看看:i.imgur.com/py65WyJ.png。这只是数组的一部分,但你明白了。许多列都有空数据,因为它从不存在的子表中提取信息。例如,与“admin”相关的列为空。此外,主要问题之一是它会从 [id] 中删除数据。即使 id 在表中从不为空,它也为空。我不知道为什么要删除它。需要注意的是,我尝试在上一个示例中添加 WHERE 子句,我也尝试使用 LEFT OUTER JOIN。两者似乎都没有任何区别。
  • 在一个完美的世界中,id 实际上会包含 id 并且诸如“admin”之类的列不会出现在该图像中,因为没有创建“admin”小部件。只创建了一个登录小部件。
  • 很抱歉,我看不懂图片,而且我似乎根本不知道你到底想要什么。选择语句检索行和列。那么为什么不编辑您的请求,向我们展示一些表格内容,比如三个小部件和其他表格中的一些条目,然后显示所需的结果行?
【解决方案2】:

将 JOIN 替换为 LEFT JOIN。它从小部件中获取所有行,并从连接表中获取相关行(如果存在)

SELECT FROM widgets
LEFT JOIN widget_login ON widget_login.id=widgets.id
LEFT JOIN widget_admin ON widget_admin.id=widgets.id
LEFT JOIN widget_facebook ON widget_facebook.id=widgets.id
WHERE ... etc etc

【讨论】:

  • 我对这个查询的问题是它包含了表中没有 id 的空行,它从我从查询中获得的数组中删除了 id,所以我可以'不要使用页面上的 id。有没有办法避免这些问题?
  • 我不明白。你能用表格的数据和想要的查询结果来说明吗?
  • 使用上面的查询,输出数组从父表中删除 id。所以它可能看起来像:[id]=>, [data2]=>"bla", [data3]=>"bla", etc.., etc... 它还包括子级不存在的行表。例如,widget_admin 不包含任何行,但结果包含所有列为空的行。它对我加入的所有子表执行此操作。
  • LEFT [OUTER] JOIN 包括左表中的所有字段(在您的情况下为小部件)和右表中的匹配字段(例如 widget_admin)。如果没有匹配的行,则空值是相关的。简单的 JOIN 只留下匹配的行,但如果你使用 2 个内部连接与 widget_admin 和 widget_login 两个表中没有相同的行。
【解决方案3】:

这实际上等于 INNER JOIN 。但仅当 id 存在于所有子表中时才会显示记录。您可以修改WHERE 条件以过滤掉行

  SELECT FROM widgets
    LEFT OUTER JOIN widget_login ON widget_login.id=widgets.id
    LEFT OUTER JOIN widget_admin ON widget_admin.id=widgets.id
    LEFT OUTER JOIN widget_facebook ON widget_facebook.id=widgets.id
    WHERE widget_login.id IS NOT NULL 
          AND  widget_admin.id IS NOT NULL 
          AND  widget_facebook.id IS NOT NULL

【讨论】:

    猜你喜欢
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 2022-08-18
    • 2016-11-17
    • 1970-01-01
    • 2015-01-05
    相关资源
    最近更新 更多