MySQL COUNT с WHERE и HAVING и ORDER BY в одном запросе - PullRequest
0 голосов
/ 24 октября 2018

Я выполняю запрос MySQL -

SELECT
u.userid, u.lastopen, 
r.auto_renew_status, r.product_id, r.is_trial_period, 
(SELECT count(apd.id) FROM apple_purchase_details as apd 
  WHERE apd.id = u.userid 
  GROUP BY u.userid 
  HAVING  count(apd.id) < 5 
) as total
FROM users as u, receipt as r 
WHERE u.userid = r.id and r.is_trial_period = 'false' and r.auto_renew_status = 0

Запрос работает нормально, но он возвращает NULL, где общее количество больше 5.

Также, когда я пытаюсьдобавьте предложение ORDER BY в u.lastopen загрузка занимает слишком много времени.Я уже проиндексировал lastopen в users таблице.

Может кто-нибудь помочь мне с этим?

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Я думаю, что вычисление количества перед основным запросом и сохранение его во временной таблице поможет эффективности, а также с использованием внутреннего ключевого слова соединения.Пожалуйста, попробуйте запрос ниже.Вместо 0 вы можете установить то, что предпочитаете, вместо NULL:

CREATE TEMPORARY TABLE t1 (SELECT count(apd.id) as Total
                           FROM apple_purchase_details as apd 
                           INNER JOIN users as u on u.userid = apd.id 
                           GROUP BY u.userid 
                           HAVING  count(apd.id) < 5);

SELECT
u.userid, u.lastopen, r.auto_renew_status, r.product_id, r.is_trial_period, 
(case when (select Total from t1) is null then 0 else (Select Total from t1) end) as total
FROM users as u, receipt as r 
INNER JOIN receipt as r on  r.id = u.userid and r.is_trial_period = 'false' and r.auto_renew_status = 0
ORDER BY u.lastopen
0 голосов
/ 25 октября 2018

Вы получаете null, потому что ваш подзапрос возвращает null, когда appid больше или равен 5. И если вы не хотите, чтобы null использовал условное CASE..WHEN..END, чтобы заменить null некоторым желаемым значением.

0 голосов
/ 24 октября 2018

Возвращается NULL, где total больше 5, потому что вы указали это с помощью HAVING count(apd.id) < 5, что означает, что подзапрос вернет ничего , если он больше 5, в результате NULLзначение для этой конкретной строки.

Если вам не нужно такое поведение, удалите ограничение HAVING в подзапросе.

Этот запрос извлекает данные из нескольких таблиц, поэтому индексируйте по lastopen вusers не сильно поможет.Я бы создал индексы для столбцов, которые используются в предложении JOIN ON.

ОБНОВЛЕНИЕ

Чтобы получить желаемый результат, попробуйте:

SELECT
u.userid, u.lastopen, 
r.auto_renew_status, r.product_id, r.is_trial_period, 
FROM users as u
JOIN receipt as r ON u.userid = r.id
JOIN (
    SELECT id, count(apd.id) FROM apple_purchase_details
    GROUP BY id
    HAVING apd.id > 5
) as apd ON apd.id = u.userid
WHERE r.is_trial_period = 'false' and r.auto_renew_status = 0
...