【问题标题】:How to make a join statement between multi table to one table?如何在多表到一个表之间进行连接语句?
【发布时间】:2025-12-13 08:50:02
【问题描述】:

首先,我有 4 个表和列,例如

  1. 供稿(id、类型、type_id)
  2. feeds_normals(id、类型、内容)
  3. feeds_links(id、类型、标题、链接)
  4. feeds_youtubes(ID、类型、标题、链接、描述、图片)
  5. feeds_photos(ID、类型、链接)

“feeds type_id”表是法线、链接、youtube、照片的匹配/链接“id”

“feeds 类型”的表正在使用标识的应该加入哪个表

例如:

feeds:
id: 1, type: "normal", type_id: 1
id: 2, type: "link", type_id: 1

feeds_normals:
id: 1, type: "normal", content: "this is a test"

feeds_links:
id: 1, type: "link", title: "This is a title", link: "http://yahoo.com"

结果:

id: 1, type: "normal", content: "this is a test", title: NULL, link: NULL
id: 2, type: "link", content: NULL, title: "This is a title", link: "http://yahoo.com"

终于

这种情况下,SQL语句怎么写?

【问题讨论】:

    标签: php mysql sql join


    【解决方案1】:

    这里有问题,可能是示例或实际数据。以下是超类型/子类型模型通常的样子:

    匹配的数据示例是:

    Feeds:
    FeedId: 1, type: "normal"
    FeedId: 2, type: "link"
    
    Feeds_Normals:
    FeedId: 1, content: "this is a test"
    
    Feeds_Links:
    FeedId: 2, title: "This is a title", link: "http://yahoo.com"
    

    请注意,子类型表中的FeedID 与超类型表中的匹配。子类型表中的Type 字段是可选的——它允许检查约束以强制类型不会在子类型表中混合。

    查询看起来像:

    select
          f.FeedID
        , n.Content      as NormalsContent
        , y.Title        as YouTubeTitle
        , y.Link         as YouTubeLink
        , y.Description  as YouTubeDescription
        , y.Image        as YouTueImage
        , k.Title        as LinksTitle
        , k.Link         as LinksLink
    from Feeds              as f
    left join Feeds_Normals as n on n.FeedId = f.FeedId
    left join Feeds_Links   as k on k.FeedId = f.FeedId
    left join Feeds_YouTube as y on y.FeedId = f.FeedId ;
    

    【讨论】:

    • 在这个图中,它有同样的问题,比如如何让一个SQL语句同时从3个表中获取数据?
    【解决方案2】:

    正如leafnode 已经建议的那样,最好更改表结构。特别是考虑到您有重复数据的事实(类型在提要表和子表中都声明)。

    我建议要么删除 feed 表,要么将所有内容映射到一个表(带有可为空的列)。如果您希望按 ID 对提要进行排序(我假设通过查看您想要的结果),后者将是实现这一点的最简单方法。

    【讨论】:

    • 在这种情况下,我知道它会重复数据,但如果我将所有内容映射到一个表,映射的表会非常大,所以我尝试存储在不同的表中。
    • @Zeuxis 所以选择两个。
    • 我仍然建议删除“父”提要表,然后在其他表中添加一个额外的时间戳列(如果确实使用提要表 ID 来订购提要)。一般来说,我认为最好不要按 ID 对记录进行排序。
    • 如果我删除“父”提要表,并继续在每个表中存储不同的数据。我可以知道如何同时从 4 个表中获取数据并按时间戳列排序吗?应该使用“union all”语句吗?
    【解决方案3】:

    一般来说 - 你不能。您描述的结构称为带有鉴别器的超类型/子类型(如果您使用 google 搜索它,您可以在 Google Books 上找到一些描述),虽然在 ER 图中很容易绘制它,但在真实数据库中很难使用。如果可以,请考虑切换到其他形式的实施鉴别器,特别是在一个表中包含所有字段。如果您无法更改结构,则必须注意编程语言中的条件并进行两次查询。

    【讨论】: