Этот запрос вычисляет столбцы free
, plus
, score
и total
основано на столбце COUNT в подзапросе.
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
столбцы вне запроса из-за возможности заказа. Также я могу включить дату.
В любом случае, чтобы упростить этот запрос?
Попробуй это:
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_id к тому, что сгруппировано и, таким образом, немного изменил ваш запрос (если у двух фильмов было одно и то же имя, но с другим идентификатором, тогда только один из id будет возвращен в вашем исходном запросе, но я предполагаю (будучи новичком MySQL, я действительно не знаю), подсчеты были бы для обоих из них взяты вместе).
HTH, Set
Ну, я проверил ваш подзапрос:
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, я не думаю, что потребуется слишком много времени для запроса. Есть ли слишком много данных? На самом деле, я тоже новичок, но у меня просто есть опыт в этом. Пожалуйста, простите меня, если это не сработает.