繁体   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