I would like to ask you PHP how to optimize the sql statement in foreach.
foreach ($res["xsumpre"] as $key => $value) {
$fsql="select count(*) from (SELECT sum(sumprem) FROM datatom.fccont where
signdate BETWEEN "$stime" AND "$etime" AND
agentcode in(select agentcode from datatom.shouxian_faagenttree
where agentstate not in("01","02") and OUTWORKDATE between "$stime" AND "$etime")
GROUP BY agentcode having sum(sumprem) <= "$value" ORDER BY sum ) as a";
$fres=$this->pgdb->mpg_select($fsql)["0"]["count"];
// var_dump($value,$fres["0"]["count"]);
$res["tate"][]=round($fres/$zres["0"]["count"],4)*100;
}
return $res;
problem description
slow interface
return result style
xsumpre tate
{
"code": 0,
"data": {
"xsumpre": [
1001066,
2002132,
3003198,
4004264,
5005330,
6006396,
7007462,
8008528,
9009594,
10010660
],
"quit": 12.21,
"tate": [
0.46,
0.46,
0.46,
0.46,
0.46,
0.46,
0.46,
0.46,
0.46,
0.46
]
},
"msg": "success"
}
it makes me feel bad. Let's sort it out first:
foreach($xxx as $key => $value){
select count(*) from (
SELECT sum(sumprem) FROM datatom.fccont where
signdate BETWEEN '$stime' AND '$etime' AND
agentcode in(
select agentcode from datatom.shouxian_faagenttree
where agentstate not in('01','02') and OUTWORKDATE between '$stime' AND '$etime'
)
GROUP BY agentcode
having sum(sumprem) <= '$value'
ORDER BY sum
) as a
}
well, now that it's a little clearer, let's start to optimize:
the first step is to bring up the innermost subquery:
$arr = $this->pgdb->mpg_select("select agentcode from datatom.shouxian_faagenttree
where agentstate not in('01','02') and OUTWORKDATE between '$stime' AND '$etime'")
foreach($xxx as $key => $value){
select count(*) from (
SELECT sum(sumprem) FROM datatom.fccont where
signdate BETWEEN '$stime' AND '$etime' AND
agentcode in($arr)
GROUP BY agentcode having sum(sumprem) <= '$value'
ORDER BY sum
) as a
}
first of all, I think you don't have to check it all at once. The first sentence I put forward sql is completely repeated, so I propose that the array that gets the result outside the loop is then stuffed into the in.
the second paragraph is optimized:
$arr<=db("select agentcode from datatom.shouxian_faagenttree
where agentstate not in('01','02') and OUTWORKDATE between '$stime' AND '$etime'")
foreach($xxx as $key => $value){
select count(*) from (
SELECT sum(sumprem) FROM datatom.fccont where
signdate BETWEEN '$stime' AND '$etime' AND
agentcode in($arr)
GROUP BY agentcode having sum(sumprem) <= '$value'
) as a
}
Finally, because I don't know your table structure and specific requirements, I don't know how to optimize it. It's just that the sentence "order by," is of no use here. Anyway, in the end, you always want count
. If you think the answer is OK, please like it and adopt it .
1. Use horizontal table to vertical table to extract the corresponding values, such as
select sum(IF(c<2,1,0)),sum(IF(c<3,1,0)),sum(IF(c<4,1,0)),... from (
select parent_id,count(id) as c from students where sex = 1 and parent_id in (
select id from members
) GROUP BY parent_id
) as a;
Note: I don't know if it would be better to put forward the middle subquery, and then serialize it and insert it into sql to do the query
2. Map each value in php