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

如何关联三张数据库表?附表结构及预期输出示例

如何关联三张数据库表以获取嵌套结构的权限数据?

问题描述

我有三张数据库表:

  • type表:字段为id、type、reason_id
  • reason表:字段为id、reason
  • permission表:字段为id、type_id,不确定是否包含reason_id字段

需要查询得到如下嵌套结构的JSON结果(已修正原示例中的JSON语法错误):

{
    "message": "Get all permissions with type and reason",
    "data": [
        {
            "id": "1",
            "types": [
                {
                    "id": "1",
                    "type": "Sick",
                    "reasons": [
                        {
                            "id": "1",
                            "reason": "covid-19"
                        }
                    ]
                }
            ]
        }
    ]
}

解决方案

情况1:permission表不存在reason_id字段

关联逻辑:permission通过type_id关联type,type通过reason_id关联reason。

基础SQL查询(以MySQL为例)

先获取关联后的扁平数据:

SELECT
    p.id AS permission_id,
    t.id AS type_id,
    t.type,
    r.id AS reason_id,
    r.reason
FROM permission p
LEFT JOIN `type` t ON p.type_id = t.id
LEFT JOIN reason r ON t.reason_id = r.id;

后端组装嵌套结构(以Python为例)

SQL无法直接返回嵌套JSON,需通过后端代码将扁平结果组装成目标结构:

# 假设sql_query_result是SQL查询返回的扁平数据列表
sql_query_result = [
    {"permission_id": "1", "type_id": "1", "type": "Sick", "reason_id": "1", "reason": "covid-19"}
]

permission_map = {}
for row in sql_query_result:
    perm_id = row["permission_id"]
    # 初始化权限条目
    if perm_id not in permission_map:
        permission_map[perm_id] = {
            "id": perm_id,
            "types": []
        }
    perm_item = permission_map[perm_id]
    
    # 检查当前type是否已存在
    type_item = next((t for t in perm_item["types"] if t["id"] == row["type_id"]), None)
    if not type_item:
        type_item = {
            "id": row["type_id"],
            "type": row["type"],
            "reasons": []
        }
        perm_item["types"].append(type_item)
    
    # 添加reason到对应type的列表
    type_item["reasons"].append({
        "id": row["reason_id"],
        "reason": row["reason"]
    })

# 组装最终结果
final_result = {
    "message": "Get all permissions with type and reason",
    "data": list(permission_map.values())
}

情况2:permission表存在reason_id字段

关联逻辑:permission可直接通过自身reason_id关联reason,同时保留与type的关联,兼容两种关联场景。

基础SQL查询(以MySQL为例)

SELECT
    p.id AS permission_id,
    t.id AS type_id,
    t.type,
    r.id AS reason_id,
    r.reason
FROM permission p
LEFT JOIN `type` t ON p.type_id = t.id
LEFT JOIN reason r ON p.reason_id = r.id OR t.reason_id = r.id;

后端组装逻辑

与情况1的后端代码完全一致,只需确保SQL返回字段与代码中的键名对应即可。


可选:PostgreSQL直接生成嵌套JSON

如果使用PostgreSQL,可利用原生JSON函数直接在SQL中生成目标结构,无需后端额外处理:

SELECT
    json_build_object(
        'message', 'Get all permissions with type and reason',
        'data', json_agg(
            json_build_object(
                'id', p.id,
                'types', (
                    SELECT json_agg(
                        json_build_object(
                            'id', t.id,
                            'type', t.type,
                            'reasons', (
                                SELECT json_agg(
                                    json_build_object('id', r.id, 'reason', r.reason)
                                ) FROM reason r WHERE r.id = t.reason_id
                            )
                        )
                    ) FROM `type` t WHERE t.id = p.type_id
                )
            )
        )
    ) AS result
FROM permission p;

内容的提问来源于stack exchange,提问作者Vireak Ron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:55:23