MySQL中基于其他选择的多选结果

3

我有这样一个数据库:

schema

例如,用户请求带有 posts.post_id = 1 的所有 post 数据。现在我想从其他表中获取额外的数据:

  • 一些来自表 posts 的字段,其中 post_id = 1
  • 所有来自表 postmeta 的字段,其中 post_id = 1
  • 一些来自表 users 的字段,这取决于 post_id = 1 中的 posts.user_id
  • 所有具有与 post_id = 1 相关联的关系的表 files 的字段
  • 一些与 post_id = 1 相关联的表 terms 的字段

在 PHP 中,我可以简单地运行 5 个查询来获取此信息,但我想这不是最好的方法,因为 MySQL 能够更快地执行。

更新详情:

-- select from posts
SELECT
    posts.post_id,
    posts.post_title,
    posts.post_name,
    posts.post_content,
    posts.post_status,
    posts.post_type,
    posts.post_modified_gmt,
    posts.post_date_gmt,
    posts.post_mime_type,
    posts.user_id
FROM
    posts
WHERE
    posts.post_id = 1

--select from postmeta
SELECT
    postmeta.postmeta_value,
    postmeta.postmeta_key,
    postmeta.postmeta_id
FROM
    postmeta
WHERE
    postmeta.post_id = 1


SELECT
    files.file_size,
    files.file_type,
    files.file_name,
    files.file_id
FROM
    files
INNER JOIN file_relationships ON files.file_id = files.file_id
WHERE
    file_relationships.post_id = 1

--select from terms
SELECT
    terms.term_id,
    terms.term_name,
    terms.term_slug,
    terms.term_taxonomy,
    terms.term_description,
    terms.term_group,
    terms.term_parent,
    terms.term_count
FROM
    term_relationships
INNER JOIN terms ON term_relationships.term_id = terms.term_id
WHERE
    term_relationships.post_id = 1

--select from users , users.user_id depend on posts.user_id 
SELECT
    users.user_id,
    users.user_name,
    users.user_email,
    users.user_nicename,
    users.user_password,
    users.user_displayname,
    users.user_role,
    users.user_bio
FROM
    users
WHERE
    users.user_id = 1

这是我用PHP运行的查询信息的代码: 数据库+数据 有没有仅使用MySQL来完成这个操作的方法呢?

2
你应该学习SQL的JOIN操作。 - andy
2
我了解一些MySQL的JOIN,我写了查询但结果似乎不太好,我获得了4条记录,包含posts字段(在4个记录中重复)和postmeta字段。这对性能来说不好,对吧? - Death Programmer
2
请添加一些示例内容和所需结果,以及为什么这是期望的结果的解释。 - VMai
2
首先,为您的问题获取正确的查询。 您可能会惊讶MySQL可以多么聪明地提高性能... - andy
2个回答

3
一个查询并不总是比多个查询更好。在这种情况下,我建议仅组合您的一对一关系,但保持多对一关系的单独查询,因为如果一个帖子有3个术语和2个文件,将两个多对一关系连接起来会产生6行。
选择帖子、用户和帖子元数据。
select * from posts p
join postmeta pm on pm.post_id = p.post_id
join users u on u.user_id = p.user_id
where p.post_id = 1

选择文件
select f.* from files f
join file_relationships fr on fr.file_id = f.file_id
join posts p on p.post_id = fr.post_id
where p.post_id = 1

选择术语

select t.* from terms t
join term_relationships tr on tr.term_id = t.term_id
join posts p on p.post_id = tr.post_id
where p.post_id = 1

2
因为只有具有“帖子”的“用户”才具有一对一的关系,所以我必须运行4个查询来获取这些数据? - Death Programmer
2
在这种情况下,是的,将会有4个查询。 - FuzzyTree

1

这应该是你所需要的所有JOIN,根据需要修改SELECT列表。

select p.post_id,
       p.post_title,
       p.user_id,
       u.user_name,
       u.user_email,
       pm.*,
       f.*
  from posts p
  join postmeta pm
    on p.post_id = pm.post_id
  join users u
    on p.user_id = u.user_id
  join file_relationships fr
    on p.post_id = fr.post_id
  join files f
    on fr.file_id = f.file_id

* 表示使用指定别名的表中的所有列。


2
如果我使用JOIN,会有10个或更多重复的列,这对性能来说不好。有没有其他方法可以获取该字段? - Death Programmer
2
你是指列还是行? - VMai
2
你可以带回任何你想要的列。在你的问题中,你没有说你想要哪些列,你只说了“一些列”。你可以修改选择列表来带回你想要的列,或者在你的问题中指定你想要的列,我会将其更改为仅带回这些列。 - Brian DeMilia
2
有些表之间存在一对多的关系。例如,一个帖子可能有5个文件。因此,仅基于与该表的连接,您就会为该帖子拥有5行重复记录(每个帖子的每个文件都有一行)。如果您只想要一行记录来表示一个帖子,您必须以某种方式进行聚合。您想要该帖子的第一个文件吗?最后一个文件?等等。如果您提供示例数据和期望结果,我们可以进一步帮助您。我们必须知道您想如何聚合每种一对多的情况以及这些情况是什么。 - Brian DeMilia
2
我想要所有的行,我认为我可以用@FuzzyTree的方法实现。 - Death Programmer
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接