我在我的选择查询中使用子查询,但正如您在示例中所看到的,我使用type='jump'
执行相同的子查询两次以与不同的值进行比较。优化此查询的最佳方法是什么?感谢
SELECT * FROM tableone WHERE ONE > 10 AND PAS != '' AND CMD = 'xxx'
AND (SELECT COUNT() FROM tabletwo WHERE tabletwo.id = tableone.id AND TYPE='walk' AND TIMESTAMP > $last24hours) <= $walklimit
AND (SELECT COUNT() FROM tabletwo WHERE tabletwo.id = tableone.id AND TYPE='jump' AND TIMESTAMP > $last24hours) <= $jumpslimit
AND (SELECT COUNT() FROM tabletwo WHERE tabletwo.id = tableone.id AND TYPE='jump' AND TIMESTAMP > $last24hours) <= $jumpsHOURlimit
LIMIT 1;
更新:使用JOIN
或使用min()简单的解决方案更好?
答案 0 :(得分:2)
您的两个子查询完全相同。唯一的区别在于极限。因此,请使用min()
:
SELECT t1.*
FROM tableone t1
WHERE t1.ONE > 10 AND t1.PAS <> '' AND t1.CMD = 'xxx' AND
(SELECT COUNT(*)
FROM tabletwo
WHERE tabletwo.id = tableone.id AND TYPE = 'walk' AND TIMESTAMP > $last24hours
) <= $walklimit AND
(SELECT COUNT(*)
FROM tabletwo
WHERE tabletwo.id = tableone.id AND TYPE='jump' AND TIMESTAMP > $last24hours
) <= min($jumpslimit, $jumpsHOURlimit)
LIMIT 1;
答案 1 :(得分:1)
如果我正确理解您的问题,您还可以使用JOIN
将它们合并为一个查询,然后使用COUNT
和CASE
来过滤结果:
SELECT t1.*
FROM tableone t1
JOIN tabletwo t2 ON tabletwo.id = tableone.id AND t2.TIMESTAMP > $last24hours
WHERE t1.ONE > 10 AND t1.PAS <> '' AND t1.CMD = 'xxx'
GROUP BY t1.id
HAVING COUNT(CASE WHEN t2.TYPE='walk' THEN 1 END) <= $walklimit
AND COUNT(CASE WHEN t2.TYPE='jump' THEN 1 END) <= min($jumpslimit, $jumpsHOURlimit)
LIMIT 1;