【问题标题】:SQL Query for joining multiple tables containing multiple rows - The right way?用于连接包含多行的多个表的 SQL 查询 - 正确的方法?
【发布时间】:2014-03-29 21:13:05
【问题描述】:

我有 4 个以下模式的表:

#1 : Table USER
user_id | user_details....

#2 : Table POSTS
post_id | user_id | post_details....

#3 : Table REPLIES
reply_id | post_id | by_user_id | reply_details...

#4 : Tables REPLY_PHOTOS
photo_id | reply_id | photo_details...

我想检索特定用户的所有帖子以及对他们的回复和回复中的照片。上表中列的每次使用都在外键约束中。

SELECT USER.user_id, POST.post_id, REPLIES.reply_id, REPLY_PHOTOS.photo_id
FROM USER WHERE USER.user_id = 1
LEFT JOIN POST on USER.user_id = POST.user_id
LEFT JOIN REPLIES on POST.post_id = REPLIES.post_id
LEFT JOIN REPLY_PHOTOS on REPLIES.reply_id = REPLY_PHOTOS.reply_id;

我面临的问题是,当我正常使用连接时,我得到的行我怀疑不是好的做法。

user_id = 1 得到的结果示例:

user_id | post_id | reply_id | photo_id
--------Post 1 - Reply 1 (Repeat for photos)----------------
   1         23        17         26
   1         23        17         32
   1         23        17         47
-------Post 1 - Reply 2 (Repeat for its photos)-----------
   1         23        34         12
   1         23        34         18
   1         23        34         23
   1         23        34         31
------Post 1 - Reply 3 (Contains no photos)------------
   1         23        41         null
---------Next Post for same user (contd.)----------------

由于一个用户可以有多个帖子,因此多个 post_id 与单个用户 ID 相关。 一个帖子可以包含多个回复,因此多个reply_id 与单个帖子相关。 一个回复可以包含多张照片,因此多个 photo_id 与一个回复相关。

另外,我想进一步扩展它以存储喜欢,这将是另一个麻烦。

我不知道我的架构是否需要更改(如果是,请建议我一个更好的方法)或者我是否无法理解加入的基础知识。

如果结果应该是这样,那么我怎样才能在没有太多问题的情况下遍历php 中的所有字段?

提前谢谢你。

【问题讨论】:

  • “遍历所有字段”是什么意思?数据库方案对我来说看起来不错。
  • 是的,而不是 user_id 遍历与特定 user_id 相关的所有内容。但问题是重复的结果(如果这是一个问题)。另外我使用LEFT JOIN 而不是JOIN,因为无论如何我都想要左列。
  • 嗯,根据您要达到的目标,可能有不同的方法。在这种特殊情况下你想做什么?
  • 有什么不同的可能方法,我想知道。此外,在这种情况下,我希望获取用户发布的所有帖子以及与该帖子相关的回复以及与回复相关的照片。如果有更好的方法可以做到这一点,请建议我。另外,更大的网站会如何处理这种情况?
  • 嗯,您可以通过首先获取所有帖子的 id,然后获取每个帖子的所有回复,以更结构化的方式获取数据,依此类推。但是,这当然需要更多的数据库查询。另一种选择是编写自定义“解析器”函数,将此类查询结果解析为自定义数据结构,然后用于显示所需内容。

标签: php mysql join query-optimization


【解决方案1】:

大多数时候,我会很乐意处理返回行的重复部分,而忽略它们。但是在这种情况下,您可以使用 GROUP_CONCAT。

类似这样的:-

SELECT USER.user_id, POST.post_id, GROUP_CONCAT(CONCAT_WS('~',REPLIES.reply_id, REPLY_PHOTOS.photo_id)) AS ReplyPhotoId
FROM USER WHERE USER.user_id = 1
LEFT JOIN POST on USER.user_id = POST.user_id
LEFT JOIN REPLIES on POST.post_id = REPLIES.post_id
LEFT JOIN REPLY_PHOTOS on REPLIES.reply_id = REPLY_PHOTOS.reply_id
GROUP BY USER.user_id, POST.post_id

然后您可以分解出ReplyPhotoId 字段(默认情况下在逗号上),并为结果数组的每个元素根据〜再次分解它。

【讨论】:

  • 我在想GROUP_CONCAT 但很困惑,如果我们可以像你在那里做的那样连接多个列。感谢您的回复顺便说一句。请给我一把小提琴好吗?
  • 忘掉小提琴吧。我用你的方法做对了。感谢您的指导。
  • 很高兴我不必做小提琴。一边看电视一边在笔记本电脑上打字,做任何认真的编辑都是一件痛苦的事!
猜你喜欢
  • 2020-04-23
  • 1970-01-01
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 2018-07-17
  • 1970-01-01
相关资源
最近更新 更多