如何在mysql中循环而不是循环结果

时间:2019-07-09 18:00:48

标签: php mysql

我有一个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
}

1 个答案:

答案 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);
  • COUNT不计算NULL值
  • 默认情况下,如果没有使用WASE ... THEN的CASE,则没有ELSE的CASE的评估结果为null; ELSE NULL是可选的,但已添加,以使查询逻辑更清晰。
  • 如果ticket_timestamp是实际的时间戳或日期时间数据类型,则还可以通过将日期过滤更改为类似t.ticket_timestamp >= start_date AND t.ticket_timestamp < day_after_end_date的方式来看到性能的提高
  • 您应该尝试使用参数化查询而不是字符串插入;否则,您将容易受到sql注入漏洞的影响