簡體   English   中英

重構Mysql查詢到PHP端的處理

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM