[英]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.