从多个表中检索数据并将其列在列表中

时间:2014-07-05 04:30:37

标签: php mysql

我在从两个表中检索数据然后列出它们时遇到了一些问题。我想列出用户的Feed帖子及其喜欢的活动。

  • 供稿 - 用户帖子表
  • 喜欢 - 用户喜欢的表格(因此,当用户喜欢帖子时,会在喜欢中添加一条记录(表格likes包含data,其中包含所喜欢帖子的feeds ID

我正在尝试制作:在ACTIVITY WALL中列出BOTH Feed和用户的类似活动。

因此它应该输出(按时间戳desc排序):

  • “这是用户A的帖子”
  • 显示用户C喜欢用户B的帖子
  • “这是用户B的帖子”
  • “这是用户L”的帖子
  • 显示用户A喜欢用户F的帖子
  • “这是用户F发布的帖子”
  • - 它继续 -

我当前的SQL:

SELECT * FROM feeds,likes WHERE feeds.deleted!=0 or likes.deleted!=0 ORDER BY feeds.timestamp, likes.timestamp

然而,我的问题是我不知道如何链接两个表,因为我的'feeds'中的ID与'likes'中的ID不同

4 个答案:

答案 0 :(得分:2)

要合并这两套,您可以使用 UNION ALL 设置运算符。

这样的事情:

SELECT f.timestamp    AS `timestamp`
     , 'feed'         AS `src`
     , f.feed_id      AS `id`
     , f.feed_content AS `content`
  FROM feeds f
 WHERE f.deleted!=0
 UNION ALL
SELECT l.timestamp    AS `timestamp`
     , 'like'         AS `src`
     , l.like_id      AS `id`
     , l.note         AS `content`
  FROM likes l
 WHERE l.deleted!=0
 ORDER BY 1 DESC

请注意,查询(在UNION ALL运算符的任一侧)需要根据返回的列数和每列的数据类型进行匹配。

为了适应差异,例如从一个表而不是从另一个表返回的额外列,您可以添加文字表达式来代替“缺失”列。

返回额外的src列是我们可以用来区分返回行的查询的一种方法。返回这样一个列并不是强制性的,但这是我经常觉得有用的东西。 (如果某个查询对您的用例没用,可以从每个查询中删除src列。)

请注意,也可以通过这种方式合并来自两个以上查询的结果,我们只需添加另一个UNION ALL和另一个查询。

组合结果集中的列名称是从第一个查询中确定的。第二个查询中的列名和别名将被忽略。

ORDER BY适用于整个集合,并在最后一个选择之后。

答案 1 :(得分:0)

查询应通过postID链接 F = feed表,L =喜欢表,U1 = usertable链接到已拥有的Feed,U2 = usertable链接到喜欢的表

 SELECT F.postTitle+' posted by '+ U1.username,'liked by'+U2.username  
 FROM likes L
 LEFT JOIN feeds F on (F.postID=L.postID)
 LEFT JOIN users U1 on (U1.userID=F.userID) 
 LEFT JOIN users U2 on (U2.userID=L.userID) 
 ORDER BY L.date,L.postID DESC

答案 2 :(得分:0)

当你写SELECT * FROM feeds,likes...时,你隐含地交叉连接两个表。引擎将每个表中的每个记录与另一个表中的每个记录组合在一起。这远非你想要的。

我认为你不应该“连接”两个表。粗略地说,你需要的是获得每个帖子和每个帖子,然后根据时间戳订购那个大集。

这听起来更像是两个查询之间的UNION,以及应用于整个UNION的ORDER BY。顺便说一句,UNION从来都不容易看到......

UNIONs的用处是两个子查询都需要返回相同数量的列。我不确切知道你有哪些列,我会告诉你一个可能的解决方案:

SELECT activity, timestamp FROM (
   ( SELECT CONCAT(u.name,' posted ',f.content) as activity, timestamp
     FROM user u
     JOIN feed f on (f.user_id=u.id)
     WHERE f.deleted!=0
   ) UNION
   ( SELECT CONCAT(u.name, ' liked a post by ',u2.name) as activity, timestamp
     FROM user u
     JOIN likes l on (l.user_id=u.id)
     JOIN feed f on (l.feed_id=f.id)
     JOIN user u2 on (f.user_id=u2.id)
     WHERE l.deleted!=0
   )
) as whole_result
ORDER by timestamp desc

当然,你应该修改它以匹配你的结构。

希望这有帮助!

答案 3 :(得分:0)

我认为,最好使用第3个表格,例如" actions",然后插入真实的操作。然后只需从此表中选择行,加入" posts" &安培; "用户"表

当用户发布文章时,o喜欢文章,将相应的行插入" actions"表

动作表:

|id|action_name|user_id|post_id|   date   |
 1   posted        3      3      5/7/2014
 2   liked         5      3      5/7/2014
 3   liked         4      3      6/7/2014
 4   posted        5      6      7/7/2014
 5   liked         3      6      7/7/2014

SELECT user_name a, post_title b, action_name c FROM actions c LEFT JOIN users a ON a.id=c.user_id LEFT JOIN posts b ON b.id = c.post_id ORDER BY c.date DESC LIMIT 10

然后,在循环中,根据" action_name"选择如何显示此数据。 通过这种方式,您可以扩展其他活动的墙,+使用索引以获得更好的数据库性能。