简化mysql查询

l7wslrjt  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(325)

此查询计算列 free , plus , score 以及 total 基于子查询中的列数。

SELECT movie_title,movie_id,MAX(x.free_cnt) as free, MAX(x.plus_cnt) as plus, 
                (MAX(x.free_cnt) + (MAX(x.plus_cnt)*3)) AS score, (MAX(x.free_cnt) + MAX(x.plus_cnt)) AS total
                    FROM (
                        SELECT b.id as movie_id, b.movie_title as movie_title, COUNT(*) AS free_cnt, 0 as plus_cnt
                        FROM subtitles_request a1
                        LEFT JOIN movies b on a1.movie_id=b.id
                        JOIN users c on c.email=a1.email
                        WHERE c.subsc_status='0'
                        GROUP BY b.movie_title
                        UNION ALL

                        SELECT d.id as movie_id, d.movie_title as movie_title,  0 as free_cnt, COUNT(*) AS plus_cnt
                        FROM subtitles_request a2
                        LEFT JOIN movies d on a2.movie_id=d.id
                        JOIN users e on e.email=a2.email
                        WHERE e.subsc_status='1'
                        GROUP BY d.movie_title

                    ) AS x
                    GROUP BY movie_title
                    ORDER BY total DESC
                    LIMIT 10

它的执行速度很慢,我想知道是否可以简化或更改查询以提高性能。我无法计算 free , plus , score , total 由于可以按排序,所以列位于查询之外。我也可以加入日期。
要简化这个查询吗?

wfauudbj

wfauudbj1#

试试这个:

SELECT b.movie_title, x.movie_id, MAX( x.free_cnt ) AS free, MAX( x.plus_cnt ) AS plus, 
           ( MAX( x.free_cnt ) + ( MAX( x.plus_cnt ) * 3 ) ) AS score, ( MAX( x.free_cnt ) + MAX( x.plus_cnt ) ) AS total
    FROM ( SELECT a.movie_id,
                  SUM( IF( c.subsc_status = '0', 1, 0 ) ) AS free_cnt, 
                  SUM( IF( c.subsc_status = '1', 1, 0 ) ) AS plus_cnt
           FROM subtitles_request a1
           JOIN users c on c.email=a1.email
           WHERE c.subsc_status in ('0','1')
           GROUP BY a.movie_id
         ) AS x
    LEFT JOIN movies b on x.movie_id = b.id
    GROUP BY movie_title, movie_id
    ORDER BY total DESC
    LIMIT 10

也许我简化得太多了。此外,我不习惯只对一些非聚合字段进行分组,因此我将movie\u id添加到分组依据中,从而稍微更改了您的查询(如果两部电影的名称相同,但id不同,那么在您的原始查询中只会返回一个id,但我猜(作为mysql新手,我真的不知道)计数将为他们两个一起)。
hth,设置

kupeojn6

kupeojn62#

好吧,我已经检查了你的子查询:

SELECT b.id as movie_id, b.movie_title as movie_title, COUNT(*) AS free_cnt, 0 as plus_cnt
FROM subtitles_request a1
LEFT JOIN movies b on a1.movie_id=b.id
JOIN users c on c.email=a1.email
WHERE c.subsc_status='0'
GROUP BY b.movie_title
UNION ALL

SELECT d.id as movie_id, d.movie_title as movie_title,  0 as free_cnt, COUNT(*) AS plus_cnt
FROM subtitles_request a2
LEFT JOIN movies d on a2.movie_id=d.id
JOIN users e on e.email=a2.email
WHERE e.subsc_status='1'
GROUP BY d.movie_title

“union all”旁边的语句可以替换为一个条件为的语句 c.subsc_status IN('0','1') . 你可以尝试使用case-when语句 0 as free_cnt, COUNT(*) AS plus_cnt ,就像 IFNULL((CASE WHEN e.subsc_status='1' THEN COUNT(*)),0) as free_cnt . 这不是一个复杂的sql语句,我不认为查询它会花费太多时间。数据太多了吗?事实上,我也是一个新手,但我只是有一些经验。如果不行,请原谅我。

相关问题