我有7个表来存储用户数据,例如帖子,图片,更新,评论,喜欢,重新发布和用户本身。
以下是我的问题:如何使用正确的查询来执行连接表? 我正在使用此查询:
if ( ! function_exists('getTimeline'))
{
function getTimelines($contributor = null, $limit = 10, $offset = 0)
{
$CI =& get_instance();
$CI->db->select('
abycms_posts.*,
abycms_images.imageID,
abycms_images.contributor as owner,
abycms_images.imageContent,
abycms_images.imageFile,
abycms_images.imageSlug,
abycms_images.timestamp as date,
abycms_images.visits_count as visits,
abycms_updates.updateID,
abycms_updates.userID as updater,
abycms_updates.updateContent,
abycms_updates.visibility,
abycms_updates.timestamp as update_time,
abycms_likes.likeID,
abycms_likes.userID as userLike,
abycms_likes.type as likeType,
abycms_likes.timestamp as like_time,
abycms_comments.commentID,
abycms_comments.userID as commentUser,
abycms_comments.type as commentType,
abycms_comments.timestamp as comment_time,
abycms_reposts.repostID,
abycms_reposts.userID as repostUser,
abycms_reposts.type as repostType,
abycms_reposts.timestamp as repost_time
');
$CI->db->from('abycms_users');
$CI->db->join('abycms_posts', 'abycms_posts.contributor = abycms_users.userID', 'left');
$CI->db->join('abycms_images', 'abycms_images.contributor = abycms_users.userID', 'left');
$CI->db->join('abycms_updates', 'abycms_updates.userID = abycms_users.userID', 'left');
$CI->db->join('abycms_likes', 'abycms_likes.userID = abycms_users.userID', 'left');
$CI->db->join('abycms_comments', 'abycms_comments.userID = abycms_users.userID', 'left');
$CI->db->join('abycms_reposts', 'abycms_reposts.userID = abycms_users.userID', 'left');
$CI->db->where('abycms_users.userID', $contributor);
$CI->db->limit($limit, $offset);
// How to order results by newest `timestamp` for posts, images, updates, comments, likes or reposts?
$CI->db->order_by('abycms_posts.timestamp', 'desc');
// How to handle not duplicate `postID` or `imageID` also group it by different `type`s?
$CI->db->group_by('abycms_posts.postID, abycms_images.imageID');
$query = $CI->db->get();
if($query->num_rows() > 0)
{
return $query->result_array();
}
else
{
return array();
}
}
}
我的观点是处理不同类型的结果:
foreach(getTimelines($page['userID'], $limit, $offset) as $row)
{
if($row['updateID'] != null) // Updating Status
{
// This status updates
}
elseif($row['postID'] != null) // Writing Article
{
// This is posts
}
elseif($row['imageID'] != null) // Uploading Image
{
// This is images
}
elseif($row['commentID'] != null) // Commented on Post
{
// This is comments
}
elseif($row['likeID'] != null) // Liking User Post
{
// This is likes
}
elseif($row['repostID'] != null) // Reposting User Post
{
// This is reposts
}
}
当我使用上述查询时,结果显示但我不知道要分离内容类型。它始终显示为状态更新,所有唯一ID如postID,imageID,updateID,repostID,likeID和commentID都具有相同的值。
答案 0 :(得分:1)
该查询正在生成部分交叉产品。
对于从_users
返回的每一行,MySQL都会从_likes
获取所有匹配的行。
为了举例,我们假设从_users
返回了一行,_likes
中有四个匹配的行,返回(到目前为止)总共四行。来自_users
的行与来自_likes
的四行中的每一行匹配。来自_users
的行中的所有列都会复制到四行中的每一行中。
从_posts
表中,为了举例,我们假设有两个行匹配。因此,从_posts
返回的这两行中的每一行都将匹配我们已经拥有的四行中的每一行,总共给出了八行。 (从_posts
返回的每一行都与从_likes
返回的每一行匹配。)
在_comments
表中,对于此示例,假设返回了六行。这些行中的每一行都与我们已有的八行匹配,总共有48行。并且每个表的列中的许多值都会“重复”到新行中,因为新表中的多行都会被加入。
依此类推,每个额外的连接表。
这是表格的部分“交叉产品”。 (半笛卡尔积?)
如果您想要返回_posts
的不同列表,_likes
的不同列表以及_comments
的不同列表等,那么您可以运行单独的查询<每个表都有/ em>。这样可以避免由于连接操作而发生的“重复”。这可能是最简单的方法。
否则,如果您想获得_posts
,_likes
,_comments
等的明确列表。在当前查询返回的结果集之外,您需要客户端筛选行以过滤掉重复的_posts
,_likes
,_comments
。您需要为返回的行中包含的每个表都有唯一的标识符。
基本上,您的代码需要为_posts
,_likes
,_comments
构建单独的数组。对于结果集中的每一行,您需要检查_posts
列中的值是否来自您已经处理过的_posts
行。如果它已经处理过,请将其丢弃,否则将其添加到阵列中。基本上将行重复数据删除为每个表的单独结果,采用从每个表的单独查询中获得的形式。