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

Sequelize aggregate group by 按audioId分组失效及关联数据查询问题

问题根源

  1. 你当前group配置中加入了user.id字段,分组逻辑变成了「每个音频+每个投票用户」单独成组,自然会出现每条投票数据单独展示的情况。
  2. 直接include User模型未做特殊配置时,Sequelize默认会自动将关联表的主键加入分组规则,这也是user.id破坏分组的核心诱因。
  3. Audio关联下的group: ['audioFolderId.id']属于无效配置,不仅没用还可能导致额外的分组逻辑异常。

解决方案

按以下步骤调整代码即可实现按audioId分组,同时保留需要的关联数据:

  1. 修正分组规则:仅保留和audioId一一对应的分组字段,删除user.id
  2. 调整User关联逻辑:你已经通过MAX(globalVotes.user_Id)拿到了最新投票的用户ID,不需要直接关联整个User表,避免触发自动分组。可以在拿到聚合结果后单独根据用户ID查用户名,或者直接用子查询在字段中获取用户名
  3. 删除Audio关联下的无效group配置

调整后代码参考

try {
    const votes = await globalVotes.findAll({
        // audio和audioFolder的主键和audioId一一对应,不会破坏分组规则
        group: ['audioId', 'mediaType', 'audio.id', 'audio.audioFolderId.id'],
        attributes: [
            'audioId',
            'mediaType',
            [Sequelize.fn('SUM', Sequelize.col('totalVote')), 'total_vote'],
            [Sequelize.fn('MAX', Sequelize.col('voterEmail')), 'latest_email'],
            [Sequelize.fn('COUNT', Sequelize.col('voteCount')), 'total_vote_count'],
            [Sequelize.fn('MAX', Sequelize.col('vottingNum')), 'latest_number'],
            [Sequelize.fn('MAX', Sequelize.col('globalVotes.user_Id')), 'latest_user_id'],
            [
                Sequelize.fn('MAX', Sequelize.col('globalVotes.updatedAt')),
                'latest_time',
            ],
            // 可选:直接用子查询拿到最新用户名,不需要二次查询
            [Sequelize.literal(`(SELECT fullName FROM User WHERE id = MAX(globalVotes.user_Id))`), 'latest_user_name']
        ],
        include: [
            {
                model: Audio,
                attributes: ['aTitle', 'aImage', 'audioFolderId'],
                include: [
                    {
                        model: AudioFolder,
                        attributes: ['folderName'],
                    },
                ],
            },
            // 删掉原来的User关联,避免自动加group字段
        ],
        order: [[Sequelize.fn('SUM', Sequelize.col('totalVote')), 'DESC']],
        raw: true,
        nest: true,
    });
    // 如果你没写上面的子查询,也可以在这里批量查用户名称补充到结果里
    // const userIds = votes.map(v => v.latest_user_id).filter(Boolean);
    // const users = await User.findAll({ where: {id: userIds}, attributes: ['id', 'fullName'] });
    // const userMap = new Map(users.map(u => [u.id, u.fullName]));
    // votes.forEach(v => v.latest_user_name = userMap.get(v.latest_user_id));
    console.log(votes);
    res.status(200).render('admin/chart/audio/index', {
        title: 'Manage Audio Votes',
        votes,
    });

内容的提问来源于stack exchange,提问作者freelanceing mindset

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:54:03