我有一个while循环,在这个循环中,我进行sql查询,并根据结果创建一个数组,但我想通过避免while循环并进行一个sql查询来改善这一点。
我尝试了sub_queries,但这并没有改善我的执行时间。它实际上使它变慢。我在查询中使用的表中有主键和索引。
$start_date = $_REQUEST['start_date'];
$end_date = $_REQUEST['end_date'];
$location_ids = $_REQUEST['location_id'];
while (strtotime($start_date) <= strtotime($end_date)) {
$sql="SELECT
TRUNCATE((SELECT
COUNT(*)
FROM
ticket
WHERE
DATE(ticket_timestamp) = '{$start_date}'
AND outcome_id = 3
AND ticket.location_id IN ($location_ids) ) / (SELECT
COUNT(*)
FROM
ticket
WHERE
outcome_id < 4
AND DATE(ticket_timestamp) = '{$start_date}'
AND ticket.location_id IN ($location_ids) ) * 100,
0) AS value;";
if ($result = $this->db->query($sql)) {
$row = $result->fetch_row();
$newarray = array("name"=>$start_date,"value"=>$row[0]);
if ($row[0] >= "0")
array_push($response->result, $newarray);
$start_date = date("Y-m-d", strtotime("+1 day", strtotime($start_date)));
$i++;
}
}
$response->success = true;
$response->total = count($response->result);
return $response;
这些是我目前的结果,预期结果应该仍然相同
{
"success":true,
"result":[
{"name":"2019-07-08","value":"17"},
{"name":"2019-07-09","value":"18"}
],
"total":2
}
答案 0 :(得分:0)
您可以使用聚合来消除循环的需要,并可以使用条件聚合来完全消除对子查询的需求:
SELECT TRUNCATE(
COUNT(CASE WHEN t.outcome_id = 3 THEN 1 ELSE NULL END) / COUNT(*) * 100
,0)
FROM ticket AS t
WHERE outcome_id < 4
AND DATE(t.ticket_timestamp) BETWEEN '{$start_date}' AND '{$end_date}'
AND t.location_id IN ($location_ids)
GROUP BY DATE(t.ticket_timestamp);
ELSE NULL
是可选的,但已添加,以使查询逻辑更清晰。ticket_timestamp
是实际的时间戳或日期时间数据类型,则还可以通过将日期过滤更改为类似t.ticket_timestamp >= start_date AND t.ticket_timestamp < day_after_end_date
的方式来看到性能的提高