MySQL 在同一个查询中使用 WHERE 和 HAVING 和 ORDER BY 进行计数

MySQL COUNT with WHERE and HAVING and ORDER BY in the same query

我是运行一个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。

此外,当我尝试在 u.lastopen 上添加 ORDER BY 子句时,加载时间太长。我已经在 users table.

中索引了 lastopen

谁能帮我解决这个问题?

它是 returning NULL,其中 total 大于 5,因为你用 HAVING count(apd.id) < 5 指定了,这意味着子查询将 return nothing 当它大于 5 时,导致该特定行的 NULL 值。

如果您不希望出现这种行为,请删除子查询中的 HAVING 约束。

此查询从多个表中检索数据,因此 userslastopen 上的索引不会有太大帮助。我会在 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

我认为在主查询之前计算计数并将其保存在临时文件中 table 将有助于提高效率,以及使用 inner join 关键字。请尝试下面的查询。您可以设置您喜欢的而不是 NULL,而不是 0:

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

当 appid 大于或等于 5 时,您的子查询 returns 为 null。如果您不想使用 null,请使用条件 CASE..WHEN..END 将 null 替换为一些期望值。