如何修改此查询,以便按每篇帖子的评论数量对结果进行排序?

时间:2017-04-27 00:24:15

标签: php mysql

我已经坚持了一个星期左右。有一个SQL查询从数据库中提取帖子。我需要添加一个LEFT JOIN,这样我就可以根据每个帖子的评论数来订购帖子。从评论最多的帖子到评论最少的帖子。这是我的问题:

SELECT DISTINCT 
    wallposts.p_id,
    wallposts.is_profile_notes,
    wallposts.times_viewed,
    wallposts.columnTimesShared,
    wallposts.marked,wallposts.secure_id,
    wallposts.reshared,wallposts.group_id,
    wallposts.totaluploads,
    wallposts.WallUploadID,
    wallposts.type,
    wallposts.value,
    wallposts.media,
    wallposts.youtube,
    wallposts.post_type,
    wallposts.privacy,
    wallposts.tagedpersons,
    wallposts.with_friends_tagged,
    wallposts.emotion_head,
    wallposts.selected_emotion,
    wallposts.title,
    wallposts.url,
    wallposts.description,
    wallposts.cur_image,
    wallposts.uip,
    wallposts.likes,
    wallposts.userid,
    wallposts.posted_by,
    wallposts.post as postdata,
    wallusers.*, 
    UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
    PosterTable.mem_pic as posterPic,
    PosterTable.gender as posterGender,
    PosterTable.oauth_uid as poster_oauth_uid,
    PosterTable.username as posterUsername, 
    PosterTable.mem_fname as posterFname,
    PosterTable.work as posterWork, 
    PosterTable.mem_lname as posterLname,
    walllikes_track.id as PostLikeFound,
    wallposts.date_created
FROM 
    wallusers,
    wallusers as PosterTable,
    wallposts 
LEFT JOIN
    walllikes_track
ON
    wallposts.p_id = walllikes_track.post_id
AND 
    walllikes_track.member_id = ".$user_id." 
WHERE
    wallusers.active = 1 
AND
    PosterTable.active = 1
AND
    wallposts.group_id IN (".$groups.")
AND
    wallposts.group_id != 0
AND
    PosterTable.mem_id = wallposts.posted_by
AND
    wallposts.marked < ".$this->flagNumber."
AND
    wallusers.mem_id = wallposts.posted_by

&#34; wallposts&#34;是我的帖子的表的名称,并具有p_id。和#34;墙评论&#34;是包含注释的表的名称,其中包含一个名为post_id的列,用于将其链接到帖子。请帮助我按照评论数量订购帖子。我试过了,但我的屏幕空白,我的程序每次都崩溃了:

SELECT DISTINCT 
    wallposts.p_id,
    wallposts.is_profile_notes,
    wallposts.times_viewed,
    wallposts.columnTimesShared,
    wallposts.marked,wallposts.secure_id,
    wallposts.reshared,wallposts.group_id,
    wallposts.totaluploads,
    wallposts.WallUploadID,
    wallposts.type,
    wallposts.value,
    wallposts.media,
    wallposts.youtube,
    wallposts.post_type,
    wallposts.privacy,
    wallposts.tagedpersons,
    wallposts.with_friends_tagged,
    wallposts.emotion_head,
    wallposts.selected_emotion,
    wallposts.title,
    wallposts.url,
    wallposts.description,
    wallposts.cur_image,
    wallposts.uip,
    wallposts.likes,
    wallposts.userid,
    wallposts.posted_by,
    wallposts.post as postdata,
    wallusers.*, 
    UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
    PosterTable.mem_pic as posterPic,
    PosterTable.gender as posterGender,
    PosterTable.oauth_uid as poster_oauth_uid,
    PosterTable.username as posterUsername, 
    PosterTable.mem_fname as posterFname,
    PosterTable.work as posterWork, 
    PosterTable.mem_lname as posterLname,
    walllikes_track.id as PostLikeFound,
    wallposts.date_created,

    p.p_id,
    c.postcount

FROM 
    wallusers,
    wallusers as PosterTable,
    wallposts,
    wallposts as p


INNER JOIN  (
                SELECT
                    post_id,
                    count(*) AS postcount
                FROM
                    wallcomments
                GROUP BY
                    post_id
            ) as c
on
    p.p_id = c.post_id


LEFT JOIN
    walllikes_track
ON
    wallposts.p_id = walllikes_track.post_id
AND 
    walllikes_track.member_id = ".$user_id." 
WHERE
    wallusers.active = 1 
AND
    PosterTable.active = 1
AND
    wallposts.group_id IN (".$groups.")
AND
    wallposts.group_id != 0
AND
    PosterTable.mem_id = wallposts.posted_by
AND
    wallposts.marked < ".$this->flagNumber."
AND
    wallusers.mem_id = wallposts.posted_by

我做错了什么?

1 个答案:

答案 0 :(得分:0)

尝试以相反的方向进行

select a.post_id, ...all the rest ... 
from 
   (select post_id, count(1) as c from  wallcomments group by 1 order by 2 desc) a
left join wallcomments w on w.p_id = a.post_id ...
带有列索引/数字而不是列名的

group byorder by应该至少可以在MySQL和Oracle上运行,也可能是其他的

我想说的是,在您的查询中,您试图“从多个表中获取所有内容”,然后按“另一个表中的某些数据”排序,可能有助于首先关注获取列表post_ids按照你想要的数量排序,然后通过其他表中的数据“丰富”每条记录(通过加入post_id)。

你也可以在评论表上创建一个只显示post_id的视图,no_of_comments

稍后修改:在更好地查看您的查询后,在我看来它有一些不加起来的东西...例如,为什么你使用的是wallusers表两次?你似乎以同样的方式链接到它(也许我已经失去了一些东西),无论如何在我摆脱了一些摆弄之后

SELECT 
    c.*, -- the "count collection" data (also ensures distinct post_id, because it has group by
    p.*, -- posts fields
    u.*, -- user data
    l.* -- likes data
FROM 
    (select post_id, COUNT(1) as comment_count FROM  wallcomments GROUP BY post_id) as c
    LEFT JOIN wallposts as p on p.p_id = c.post_id
    LEFT JOIN wallusers as u on u.mem_id = p.posted_by
    LEFT JOIN walllikes_track as l on l.post_id = p.p_id
WHERE 
    l.member_id = ".$user_id." AND
    p.group_id IN (".$groups.") AND
    p.marked < ".$this->flagNumber."
ORDER BY c.comment_count DESC

你必须调整它以获得所需的列列表并添加任何其他条件。

作为旁注,请查看“准备语句”,而不是构建和执行原始查询(也请检查SQL注入)