APIJSON icon indicating copy to clipboard operation
APIJSON copied to clipboard

多对多关联查询咨询

Open zxcwindy opened this issue 1 year ago • 2 comments

Description

目前有三张表,分别是user、org(组织架构)、org_user。其中user和org是多对多关系,一个org可以对应多个user,一个user也可以对应多个org,他们之间的关联关系是通过org表记录的(org_user表字段为org_id和user_id)。

现在想实现一个一对多查询的效果,即查询每个用户和他对应的组织列表信息。

首先尝试如下图的查询请求 2024-08-12 17-26-57-1

返回的结果有重复,查看后端执行的sql,sql语句是拼写正常的 2024-08-12 17-25-14-2

我期望的结果是如下格式的

{
  "list": [
    {
      "user": {
        "userId": "1",
        "userCnName": "管理员"
      },
      "orgList": [
        {
          "orgId": "TestOrg",
          "orgCode": "TestOrg",
          "orgName": "测试组织"
        },
        {
          "orgId": "Org",
          "orgCode": "Org",
          "orgName": "集团组织"
        }
      ]
    }
  ],
  "ok": true,
  "code": 200,
  "msg": "success",
  "time": 1723453958196
}

或者

{
  "list": [
    {
      "user": {
        "userId": "1",
        "userCnName": "管理员",
        "orgList": [
          {
            "orgId": "TestOrg",
            "orgCode": "TestOrg",
            "orgName": "测试组织"
          },
          {
            "orgId": "Org",
            "orgCode": "Org",
            "orgName": "集团组织"
          }
        ]
      }
    }
  ],
  "ok": true,
  "code": 200,
  "msg": "success",
  "time": 1723453958196
}

又尝试过如下写法,但提示异常

2024-08-12 17-19-37-3

后面研究了下,尝试了下以下写法是可以的,但是会出现1 + N 的问题,比如我User表里面有4条记录,就一共会查询5次,这个很影响性能,有没写法可以只查询一次的写法

{
  "[]": {
    "User": {},
    "Org[]": {
      "join": "&/Org/org_id@",
      "OrgUser": {
	"user_id@": "[]/User/user_id"
      },
      "Org": {
	"org_id@": "/OrgUser/org_id"
      }
    }
  },
  "format": true
}

zxcwindy avatar Aug 12 '24 09:08 zxcwindy

APP JOIN 支持跨层级,不过不支持子数组内还有 join https://github.com/Tencent/APIJSON/releases/tag/5.1.5

所以以上这个 1 + N (子数组内 join) 也只会变为 2 + N(子数组内单表查询)

TommyLemon avatar Aug 18 '24 11:08 TommyLemon

目前解析过程对 一对多、多对多 的 SQL JOIN 处理有 bug,如果不用 DISTINCT 或 GROUP BY 来去重,则会导致副表数据总是同一个,应该把现在 AbstractSQLExecutor 把结果集处理成副表单条简单 WHERE id=${id} 的查询 SQL 缓存,改为统一返回到 AbstractParser.onArrayParse 中,直接把数据赋值给副表对象,省去大量的副表解析 JSON 及执行 SQL 过程,解决以上问题

TommyLemon avatar Aug 18 '24 11:08 TommyLemon

目前解析过程对 一对多、多对多 的 SQL JOIN 处理有 bug,如果不用 DISTINCT 或 GROUP BY 来去重,则会导致副表数据总是同一个,应该把现在 AbstractSQLExecutor 把结果集处理成副表单条简单 WHERE id=${id} 的查询 SQL 缓存,改为统一返回到 AbstractParser.onArrayParse 中,直接把数据赋值给副表对象,省去大量的副表解析 JSON 及执行 SQL 过程,解决以上问题

@zxcwindy 已解决 SQL JOIN 在一对多或多对多时返回单独查询的重复副表数据,而不是 SQL 结果集里的副表数据。 (之前必须用 DISTINCT / ORDER BY 去重 或 调换主副表顺序(有的还需要把 LEFT JOIN 改为 RIGHT JOIN) 来解决,但可能结果不符合某些需求) https://github.com/Tencent/APIJSON/commit/2f5d947de21664ce77d16c20ec8851cd3d76e1dd

Image

https://apijson.cn/api/?send=true&type=JSON&url=http%3A%2F%2Flocalhost%3A8080%2Fget&json={%22[]%22:{%22count%22:3,%22join%22:%22%3C%2FComment%22,%22User%22:{%22@column%22:%22id%2Cname%22},%22Comment%22:{%22@column%22:%22id%2CuserId%22,%22userId@%22:%22%2FUser%2Fid%22}},%22@explain%22:true}

TommyLemon avatar Feb 01 '25 12:02 TommyLemon