Mysql - 按 Sql 查询排序

Mysql - Order By Sql Query

我想按参与者总数、评论总数和点赞总数对我的查询进行排序。但这不起作用。有什么解决办法吗?

而且当用户数增加时,这个查询对服务器来说会很吃力,请问有什么优化查询的建议吗?谢谢

SELECT P.*,
     distance_in_meters_lat_lng(P.post_latitude, P.post_longitude, :latitude, :longitude) as distance,
     U.user_id,
     U.user_name,
     U.user_lastName,
     U.user_photo,
     LT.time_hour,
     LC.category_name,
     (SELECT COUNT(*) FROM posts_likes PL WHERE PL.post_id = P.post_id) as likes,
     (SELECT COUNT(*) FROM comments C WHERE C.post_id = P.post_id) as comments,
     (SELECT COUNT(*) FROM posts_likes PL2 WHERE PL2.post_id = P.post_id AND PL2.user_id = :user_id) as like_status,
     (SELECT COUNT(*) FROM post_participants PC WHERE PC.post_id = P.post_id) as participants,
     (SELECT COUNT(*) FROM post_participants PC2 WHERE PC2.post_id = P.post_id AND PC2.user_id = :user_id) as participant_status,
     (SELECT user_id FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as winner,
     (SELECT user_name FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as name,
     (SELECT user_lastName FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as lastName,
     (SELECT user_photo FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as photo
     FROM posts P
     INNER JOIN users U USING(user_id)
     LEFT JOIN lot_times LT USING(time_id)
     LEFT JOIN lot_categories LC USING(category_id)
     WHERE P.user_id NOT IN (:list)
     AND P.post_type = 'lot'
     ORDER BY participants, likes, comments DESC
     LIMIT 0, 20

由于您无论如何都在查询中使用 join,我建议加入评论和点赞 table 并在 select 中获取计数,例如:

select p.id, count(l.id) as like_count, count(c.id) as comment_count
from post p
left join likes l on p.id = l.post_id
left join comments c on p.id = c.post_id
order by like_count desc, comment_count desc;

这里是SQL Fiddle.

这个查询真的很大,子查询肯定很费时间,这里还是直接用吧。

希望对您有所帮助

SELECT 
    P.*,
    distance_in_meters_lat_lng(P.post_latitude, P.post_longitude, :latitude, :longitude) as distance,
    U.user_id,
    U.user_name,
    U.user_lastName,
    U.user_photo,
    LT.time_hour,
    LC.category_name,
    COUNT(PL.*) as likes,
    COUNT(C.*) as comments,
    COUNT(PL2.*) as like_status,
    COUNT(PC.*) as participants,
    COUNT(PC2.*) as participant_status,
    PC3.user_id as winner,
    PC3.user_name as name,
    PC3.user_lastName as lastName,
    PC3.user_photo as photo,
FROM
    posts P
JOIN 
    posts_likes PL USING (post_id)
JOIN 
    comments C USING (post_id)
JOIN  
    posts_likes PL2 ON (PL2.post_id = P.post_id AND PL2.user_id = :user_id)
JOIN 
    post_participants PC USING (post_id)
JOIN 
    post_participants PC2 ON (PC2.post_id = P.post_id AND PC2.user_id = :user_id)
JOIN 
    post_participants PC3 ON (PC3.post_id = P.post_id AND is_winner = 1)
INNER JOIN 
    users U USING (user_id)
LEFT JOIN 
    lot_times LT USING (time_id)
LEFT JOIN 
    lot_categories LC USING (category_id)
WHERE
    P.user_id NOT IN (:list)  AND P.post_type = 'lot'
ORDER BY 
    participants, likes, comments DESC
LIMIT 0, 20

我终于找到了答案。

SELECT P.*,
           distance_in_meters_lat_lng(P.post_latitude, P.post_longitude, :latitude, :longitude) as distance,
           U.user_id,
           U.user_name,
           U.user_lastName,
           U.user_photo,
           LT.time_hour,
           LC.category_name,
           (SELECT COUNT(*) FROM posts_likes PL WHERE PL.post_id = P.post_id) as likes,
           (SELECT COUNT(*) FROM comments C WHERE C.post_id = P.post_id) as comments,
           (SELECT COUNT(*) FROM posts_likes PL2 WHERE PL2.post_id = P.post_id AND PL2.user_id = :user_id) as like_status,
           (SELECT COUNT(*) FROM post_participants PC WHERE PC.post_id = P.post_id) as participants,
           (SELECT COUNT(*) FROM post_participants PC2 WHERE PC2.post_id = P.post_id AND PC2.user_id = :user_id) as participant_status,
           (SELECT user_id FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as winner,
           (SELECT user_name FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as name,
           (SELECT user_lastName FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as lastName,
           (SELECT user_photo FROM post_participants PC3 WHERE PC3.post_id = P.post_id AND is_winner = 1) as photo
    FROM posts P
    INNER JOIN users U USING(user_id)
    LEFT JOIN lot_times LT USING(time_id)
    LEFT JOIN lot_categories LC USING(category_id)
    WHERE P.post_type = 'lot'
    ORDER BY participants DESC, likes DESC, comments DESC
    LIMIT 0,20