从PHPMyAdmin执行时,我有两个查询可以自行运行 - 几秒钟内。
SELECT * FROM `testresults` WHERE `SCH_NAME` <> ''
SELECT AVG(pass_rate) FROM `testresults` WHERE `SCH_NAME` <> ''
但是,当我使用第二个查询作为子查询时,查询运行速度非常慢,以至于我达到最大执行时间并且什么也得不到。
SELECT
*
FROM `testresults`
WHERE pass_rate > (SELECT
AVG(pass_rate)
FROM `testresults`
WHERE `SCH_NAME` <> ''
)
AND `SCH_NAME` <> ''
似乎正在为每一行执行子查询,尽管该平均值将是常量。在我的查询中是否有不正确的东西导致它被解释为每行的平均变化?怎么可以改写?
答案 0 :(得分:0)
尝试子查询。未经测试但是这样的事情:
SELECT * FROM
`testresults` as tr ,
(select avg(pass_rate) as passrate from testresults) as tr2
WHERE tr.`SCH_NAME` <> ''
and tr.passrate > tr2.passrate
答案 1 :(得分:0)
这适用于Transact SQL:
select
testresults.*
from
testresults
inner join
(
select
AVG(pass_rate) as calculated_avg
from testresults
where sch_name <> ''
) p
on (testresults.pass_rate > p.calculated_avg)
where sch_name <> ''
答案 2 :(得分:0)
您的表格中有很多记录有sch_name空白,即SCH_NAME=''
尝试在外部选择查询的WHERE子句中更改条件位置。 条件从左到右评估。
SELECT
*
FROM `testresults`
WHERE `SCH_NAME` <> '' AND pass_rate > (SELECT
AVG(pass_rate)
FROM `testresults`
WHERE `SCH_NAME` <> ''
)
如果记录有SCH_NAME=''
,则不会对子查询进行评估,即使用 AND 运算符时,如果第一个条件的计算结果为false,则不评估第二个条件。这称为sh ort circuiting。
更好的方法是评估AVG(pass_rate)一次,将结果存储在变量中,并在where where而不是subquery中使用此变量。
Declare @var int
SET @var = (SELECT AVG(pass_rate)
FROM `testresults`
WHERE `SCH_NAME` <> '')
SELECT
*
FROM `testresults`
WHERE `SCH_NAME` <> '' AND pass_rate >@var