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
约束。
此查询从多个表中检索数据,因此 users
中 lastopen
上的索引不会有太大帮助。我会在 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 替换为一些期望值。
我是运行一个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
约束。
此查询从多个表中检索数据,因此 users
中 lastopen
上的索引不会有太大帮助。我会在 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 替换为一些期望值。