我有一个记录交易的表。我想选择具有正好4个值为2000的事务的所有ID,但是然后排除那些具有2500个事务的事务。
SELECT t.tuserid, COUNT(*) AS CNT
FROM transactions t
WHERE t.amt = 2000
GROUP BY t.tuserid
HAVING CNT = 4;
这部分很简单,但我不确定如何有效地排除任何有t.amt = 2500的任何交易的人。对where子句的简单子查询是否最有效?
SELECT t.tuserid, COUNT(*) AS CNT
FROM transactions t
WHERE t.amt = 2000
AND t.tuserid NOT IN (SELECT x.tuserid FROM transactions x WHERE x.amt=2500)
GROUP BY t.tuserid
HAVING CNT = 4;
交易表很大,我不确定子查询是否是运行此流程的最有效方式。
答案 0 :(得分:3)
是的,子查询在这里很好。您的子查询不使用外部查询中的任何“变量”,因此它不是相关子查询。对于外部查询的每一行,通常会“执行”相关,并且通常是性能问题。
每个外部查询调用只会调用一次子查询。
此外,考虑您的索引总是一个好主意,因此在where子句中的一个索引上放置一个索引是个好主意。然后两个查询都应该在O(log(n))的复杂度类中,即使对于大数据表也应该非常快。
答案 1 :(得分:0)
我没有资源对此进行测试,但没有子查询的替代方法可能只能使用SUM
SELECT
t.tuserid,
SUM(CASE WHEN t.amt = 2000 THEN 1 ELSE 0 END CASE) AS CNT1,
SUM(CASE WHEN t.amt = 2500 THEN 1 ELSE 0 END CASE) AS CNT2
FROM
transactions t
GROUP BY
t.tuserid
HAVING
CNT1 = 4 AND CNT2 = 0;