You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQL获取用户最后访问的去重优惠券记录?

解决CodeIgniter中GROUP BY返回非最新记录的问题

你的问题核心在于:GROUP BY coupon_id会将相同优惠券ID的记录归为一组,但在没有指定聚合规则时,数据库会返回每组中任意一条的id(而非你需要的最新浏览记录的id)。比如你数据里coupon_id=65的最新记录是id=4,但结果里却出现了coupon_id=58的id=2,这就是因为GROUP BY随机取了该分组里较早的一条记录。

你想要的是「指定用户最近浏览过的4个不同优惠券,且每个优惠券只保留最新的那条浏览记录」,用DISTINCT确实达不到这个需求——因为DISTINCT只是去重结果行,无法帮你筛选出每个优惠券的最新记录。下面是两种可行的CodeIgniter实现方案:

方案一:子查询获取每个优惠券的最新记录ID

先通过子查询找出每个coupon_id对应的最大id(也就是最新浏览的那条记录),再基于这些ID查询最终结果:

// 编译子查询:获取每个coupon_id的最大id
$this->db->select_max('id');
$this->db->from('user_viewed_offer');
$this->db->where('user_id', $user_id);
$this->db->group_by('coupon_id');
$latest_ids_subquery = $this->db->get_compiled_select();

// 查询这些最新id的记录,按id倒序取4条
$this->db->select('id');
$this->db->from('user_viewed_offer');
$this->db->where_in('id', $latest_ids_subquery);
$this->db->order_by('id', 'desc');
$this->db->limit(4);

$data['coupons'] = $this->db->get()->result();
var_dump(json_encode($data['coupons']));
exit();

方案二:用窗口函数(适用于MySQL 8.0+及其他支持窗口函数的数据库)

如果你的数据库支持窗口函数,可以用ROW_NUMBER()给每个优惠券的记录按id倒序编号,然后只取编号为1的(即最新的那条):

$this->db->select('id');
$this->db->from("(
    SELECT id, coupon_id,
           ROW_NUMBER() OVER(PARTITION BY coupon_id ORDER BY id DESC) AS row_num
    FROM user_viewed_offer
    WHERE user_id = {$user_id}
) AS temp_table");
$this->db->where('row_num', 1);
$this->db->order_by('id', 'desc');
$this->db->limit(4);

$data['coupons'] = $this->db->get()->result();
var_dump(json_encode($data['coupons']));
exit();

这两种方案都会返回你期望的id=4、5、6、7的记录,解决GROUP BY返回非最新记录的问题。

内容的提问来源于stack exchange,提问作者F.Joodaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:46:59