[英]Refactoring the processing of Mysql query to PHP side
我在我的 CodeIgniter 模型中使用了一个查询来获取特定日期之间的产品列表计数。 此查询所做的是从日期在所选日期范围内和之后的日志中获取 status_from 并从日期落在用户选择的起始日期范围之前的列表中获取 added_date 并计算它。 一旦它检索到这些记录,它就会检查表中状态保存的变量,并计算sum(case when else 0)
以获得总计数。
function get_report(){
$sql = with Y as (
with recursive D (n, day) as (
select 1 as n, '2021-09-25' my_date
union
select n+1, day + interval 1 day from D
where day + interval 1 day < '2021-10-15'
) select * from D
), X as (
select Y.day,
l.*,
(select status_from from logs
where logs.refno = l.refno
and logs.logtime >= Y.day
order by logs.logtime
limit 1) logstat
from listings l, Y
where l.added_date <= Y.day
), Z as (
select X.day, ifnull(X.logstat,X.status) stat_day, count(*) cnt
from X
group by X.day, stat_day
)
select Z.day,
sum(case when Z.stat_day = 'D' then Z.cnt else 0 end ) Draft,
sum(case when Z.stat_day = 'A' then Z.cnt else 0 end ) Action,
sum(case when Z.stat_day = 'Y' then Z.cnt else 0 end ) Publish,
sum(case when Z.stat_day = 'S' then Z.cnt else 0 end ) Sold,
sum(case when Z.stat_day = 'L' then Z.cnt else 0 end ) Let
from Z
group by Z.day
order by Z.day;
$query = $this->db->query($sql);
return $query;
}
dbfiddle: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=6789f0517b194b09d235860dc794ea14
现在在这里你可以看到我在 sql 语句本身中处理我的计算,但我想在我的 php 端进行这些计算,基本上每次遇到Z.stat_day = 'D'
进行迭代,然后在 Draft 列中添加 1 和相同对于其他状态。
当前视图类:
<?php
foreach($data_total as $row ){
$draft = $row->draft ? $row->draft : 0;
$publish = $row->publish ? $row->publish : 0;
$action = $row->action ? $row->action : 0;
$sold = $row->sold ? $row->sold : 0;
$let = $row->let ? $row->let : 0;
?>
<tr>
<td><?= $row->day?></td>
<td><?= $draft ?></td>
<td><?= $publish ?></td>
<td><?= $action ?></td>
<td><?= $sold ?></td>
<td><?= $let ?></td>
</tr>
<?php } ?>
基本上我想折射我的 PHP 代码来做与 Mysql 语句正在做的相同的事情,但出于性能原因,保持查询简单并在 PHP 端进行所有处理。
首先预先构建一个永久表,其中列出了未来很远的“天数”。 当天索引。 然后使用该表代替Y
。
代替
from listings l, Y
where l.added_date <= Y.day
你可能想要
FROM Y
LEFT JOIN listings AS l ON l.added date = Y.day
WHERE Y.day BETWEEN ... AND ...
这样, listings
中缺少的天数将显示在输出中。 但是,值将显示为NULL
,因此您可能需要类似COALESCE(col, 0)
而不是NULL
。
您是否想获得“累积”小计? (cf l.added_date <= Y.day
) 如果是这样,则需要查看 8.0 的“窗口化”功能; 他们可能会快得多。 (您使用的是 8.0 吗?)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.