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

如何通过MySQL查询将多对多关联的赛事用户转为JSON数组?

完全可以直接用SQL实现这个需求!不用非得依赖JavaScript来处理,不同的关系型数据库都提供了原生的JSON聚合函数,能直接返回你要的格式。下面我给你分几种常用数据库来举例说明,还有备选的JS处理方案:

1. SQL原生实现方案

根据你使用的数据库类型,选择对应的聚合函数即可:

MySQL(5.7及以上版本)

MySQL提供了JSON_ARRAYAGG和JSON_OBJECT函数,可以直接将聚合后的用户数据转为JSON数组:

SELECT 
    t.TournamentId,
    t.name AS tournament_name,
    JSON_ARRAYAGG(
        JSON_OBJECT(
            'UserId', u.UserId,
            'name', u.name
        )
    ) AS users_list
FROM Tournament t
LEFT JOIN Tournament_Users tu ON t.TournamentId = tu.Tournament_Id
LEFT JOIN User u ON tu.User_Id = u.UserId
GROUP BY t.TournamentId, t.name;

说明:用LEFT JOIN是为了确保即使没有用户参与的赛事也能被返回,JSON_ARRAYAGG会把每个用户的信息封装成JSON对象后聚合成数组。

SQL Server(2016及以上版本)

SQL Server用FOR JSON PATH语法来生成JSON,你可以通过子查询为每个赛事生成对应的用户列表:

SELECT 
    t.TournamentId,
    t.name AS tournament_name,
    ISNULL(
        (
            SELECT u.UserId, u.name
            FROM Tournament_Users tu
            INNER JOIN [User] u ON tu.User_Id = u.UserId
            WHERE tu.Tournament_Id = t.TournamentId
            FOR JSON PATH
        ), '[]'
    ) AS users_list
FROM Tournament t;

注意:SQL Server中User是关键字,所以查询时要加方括号[User];ISNULL用来确保没有用户的赛事返回空数组[]而非NULL。

PostgreSQL(9.5及以上版本)

PostgreSQL用json_agg和json_build_object来实现JSON聚合,还可以用FILTER过滤掉空数据:

SELECT 
    t.tournamentid,
    t.name AS tournament_name,
    json_agg(
        json_build_object(
            'UserId', u.userid,
            'name', u.name
        )
    ) FILTER (WHERE u.userid IS NOT NULL) AS users_list
FROM tournament t
LEFT JOIN tournament_users tu ON t.tournamentid = tu.tournament_id
LEFT JOIN "user" u ON tu.user_id = u.userid
GROUP BY t.tournamentid, t.name;

说明:FILTER子句用来排除没有用户时产生的NULL值,确保空赛事返回的是[]而不是包含null的数组。

2. JavaScript处理方案(备选)

如果你暂时不想用SQL的JSON函数,也可以先查询出所有关联数据,再在JS中进行聚合处理:

第一步:执行基础SQL查询

SELECT 
    t.TournamentId,
    t.name AS tournament_name,
    u.UserId,
    u.name AS user_name
FROM Tournament t
LEFT JOIN Tournament_Users tu ON t.TournamentId = tu.Tournament_Id
LEFT JOIN User u ON tu.User_Id = u.UserId;

第二步:用JavaScript聚合数据

假设查询结果是一个数组results,可以这样处理:

const tournamentMap = new Map();

results.forEach(row => {
    const { TournamentId, tournament_name, UserId, user_name } = row;
    
    // 如果当前赛事还没加入映射,初始化数据
    if (!tournamentMap.has(TournamentId)) {
        tournamentMap.set(TournamentId, {
            TournamentId,
            tournament_name,
            users_list: []
        });
    }
    
    // 只有存在用户数据时才添加到列表
    if (UserId) {
        tournamentMap.get(TournamentId).users_list.push({
            UserId,
            name: user_name
        });
    }
});

// 把映射转为最终的数组格式
const finalResult = Array.from(tournamentMap.values());
console.log(JSON.stringify(finalResult, null, 2));
总结

优先推荐用SQL原生方案,因为数据库端聚合的效率更高,还能减少前端的数据处理量。如果你的数据库版本较低不支持JSON函数,再考虑用JavaScript来处理。

内容的提问来源于stack exchange,提问作者J.Kirk.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:22:27