Codeigniter连接表显示不同的内容结果

时间:2015-12-31 17:35:36

标签: php mysql codeigniter

我有7个表来存储用户数据,例如帖子,图片,更新,评论,喜欢,重新发布和用户本身。

enter image description here

以下是我的问题:如何使用正确的查询来执行连接表? 我正在使用此查询:

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都具有相同的值。

1 个答案:

答案 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行。如果它已经处理过,请将其丢弃,否则将其添加到阵列中。基本上将行重复数据删除为每个表的单独结果,采用从每个表的单独查询中获得的形式。