Prestashop1.7.8.6模块关联订单表查询客户最后下单日期方法
Prestashop 1.7.8 模块关联查询客户最后下单时间实现
你原来嵌套循环查询的写法存在N+1性能问题,客户量较大时查询效率极低,直接通过SQL左连接+聚合函数一次查询即可拿到所有需要的字段,完全符合Prestashop开发规范。
PHP端查询逻辑替换
直接替换你模块里原来的数据库查询代码即可:
$db = \Db::getInstance(); // 若需排除无效/取消/退款订单,可在JOIN条件后追加 AND o.valid = 1 $request = 'SELECT c.`id_customer`, c.`date_add`, c.`firstname`, MAX(o.`invoice_date`) AS last_order_date, CASE WHEN MAX(o.`invoice_date`) IS NULL OR MAX(o.`invoice_date`) < DATE_SUB(NOW(), INTERVAL 732 DAY) THEN "Y" ELSE "N" END AS should_be_deleted FROM `' . _DB_PREFIX_ . 'customer` c LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON c.`id_customer` = o.`id_customer` GROUP BY c.`id_customer` ORDER BY c.`id_customer` DESC LIMIT 20'; $results = $db->executeS($request); $this->context->smarty->assign('customerdata', $results);
查询逻辑说明
- 用
LEFT JOIN关联订单表,保证从未下过单的客户也不会被漏掉 MAX(o.invoice_date)直接聚合计算每个客户的最新下单日期,不需要逐用户循环查询CASE语句直接在SQL层完成待删除标记判断:无下单记录、或最后下单时间距当前超过732天的客户,标记为待删除,省去后续PHP循环做时间计算的步骤
模板端调整
修改你的tpl模板文件,新增最后下单日期、待删除标记两列展示:
<table border="1" cellpadding="6" cellspacing="0"> <thead> <tr> <th>客户ID</th> <th>注册时间</th> <th>客户名</th> <th>最后下单日期</th> <th>待删除标记</th> </tr> </thead> <tbody> {foreach $customerdata as $userone} <tr> <td style="padding-right:10px;">{$userone.id_customer}</td> <td style="padding-right:10px;">{$userone.date_add}</td> <td style="padding-right:10px;">{$userone.firstname}</td> <td style="padding-right:10px;">{if $userone.last_order_date}{$userone.last_order_date}{else}无下单记录{/if}</td> <td style="padding-right:10px;">{if $userone.should_be_deleted == 'Y'}<span style="color:red">是</span>{else}否{/if}</td> </tr> {/foreach} </tbody> </table>
注意事项
- Prestashop的
ps_orders表中valid=1的订单为已确认的有效订单,如果你不需要统计取消、退款类的无效订单,在JOIN条件后追加AND o.valid = 1即可 - 不要用原生mysqli写法做模块开发,Prestashop封装的
Db类会自动处理表前缀、SQL注入防护等兼容问题,符合官方开发规范 - 单条聚合查询的性能远高于嵌套循环查询,客户量级越大性能差异越明显
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

