使用 join 获取嵌套对象数组的 SQL 查询

2024-03-23

摘要:我将从 JSON 模式开始来描述期望。请注意具有嵌套对象数组的角色,我正在寻找一个可以通过单个查询获取它的“智能查询”。

{
    "id": 1,
    "first": "John",
    "roles": [ // Expectation -> array of objects
        {
            "id": 1,
            "name": "admin"
        },
        {
            "id": 2,
            "name": "accounts"
        }
    ]
}

user

+----+-------+
| id | first |
+----+-------+
|  1 | John  |
|  2 | Jane  |
+----+-------+

role

+----+----------+
| id |   name   |
+----+----------+
|  1 | admin    |
|  2 | accounts |
|  3 | sales    |
+----+----------+

用户角色

+---------+---------+
| user_id | role_id |
+---------+---------+
|       1 |       1 |
|       1 |       2 |
|       2 |       2 |
|       2 |       3 |
+---------+---------+

尝试01

在一个天真的方法中,我在我的nodejs代码中运行两个sql查询,在multipleStatements:true在连接字符串中。Info http://www.technicalkeeda.com/nodejs-tutorials/nodejs-mysql-multiple-statement-queries/.

User.getUser = function(id) {
    const sql = "SELECT id, first FROM user WHERE id = ?; \
        SELECT role_id AS id, role.name from user_role \
        INNER JOIN role ON user_role.role_id = role.id WHERE user_id = ?";

    db.query(sql, [id, id], function(error, result){
        const data = result[0][0]; // first query result
        data.roles = result[1];  // second query result, join in code.
        console.log(data);
    });
};

Problem:上面的代码生成了预期的 JSON 模式,但需要两个查询,由于多个语句,我能够将其缩小到尽可能小的代码单元,但在其他语言(例如 Java 或 C#)中我没有这样的奢侈,我必须创建两个函数和两个 sql 查询。所以我正在寻找一个单一的查询解决方案。


尝试02

在早期的尝试中,在 SO 社区的帮助下,我能够使用单个查询接近以下内容,但它只能帮助生成字符串数组(而不是对象数组)。

User.getUser = function(id) {
    const sql = "SELECT user.id, user.first, GROUP_CONCAT(role.name) AS roles FROM user \
        INNER JOIN user_role ON user.id = user_role.user_id \
        INNER JOIN role ON user_role.role_id = role.id \
        WHERE user.id = ? \
        GROUP BY user.id";
    db.query(sql, id, function (error, result) {
        const data = {
            id: result[0].id, first: result[0].first,
            roles: result[0].roles.split(",") // manual split to create array
        };
        console.log(data);
    });
};

尝试02结果

{
    "id": 1,
    "first": "John",
    "roles": [ // array of string
        "admin",
        "accounts"
    ]
}

生成对象数组是一个常见的要求,所以想知道 SQL 中一定有一些我不知道的东西。有没有一种方法可以借助最佳查询更好地实现这一目标。

或者让我知道没有这样的解决方案,这就是它,这就是它在生产代码中通过两个查询完成的方式。


尝试03

use role.id代替role.name in GROUP_CONCAT(role.id),这样你就可以获取一些 id,然后使用另一个子查询来获取关联的角色名称,只是想......

SQL(不起作用,只是为了思考一些东西)

SELECT 
  user.id,  user.first,  
  GROUP_CONCAT(role.id) AS role_ids, 
  (SELECT id, name FROM role WHERE id IN role_ids) AS roles
FROM user 
INNER JOIN user_role ON user.id = user_role.user_id 
INNER JOIN role ON user_role.role_id = role.id 
WHERE user.id = 1
GROUP BY user.id;

Edit

根据阿米特的回答,我了解到有这样的solution https://learn.microsoft.com/en-us/sql/relational-databases/json/format-json-output-automatically-with-auto-mode-sql-server?view=sql-server-2017在 SQL Server 中使用JSON AUTO。是的,这就是我在 MySQL 中寻找的东西。

要准确表达。

当您连接表时,第一个表中的列将生成为 根对象的属性。第二个表中的列是 作为嵌套对象的属性生成。


使用此加入查询

FOR JSON AUTO 将为您的查询结果返回 JSON

SELECT U.UserID, U.Name, Roles.RoleID, Roles.RoleName  
FROM [dbo].[User] as U 
INNER JOIN [dbo].UserRole as UR ON UR.UserID=U.UserID 
INNER JOIN [dbo].RoleMaster as Roles ON Roles.RoleID=UR.RoleMasterID
FOR JSON AUTO

上述查询的输出是

[
  {
    "UserID": 1,
    "Name": "XYZ",
    "Roles": [
      {
        "RoleID": 1,
        "RoleName": "Admin"
      }
    ]
  },
  {
    "UserID": 2,
    "Name": "PQR",
    "Roles": [
      {
        "RoleID": 1,
        "RoleName": "Admin"
      },
      {
        "RoleID": 2,
        "RoleName": "User"
      }
    ]
  },
  {
    "UserID": 3,
    "Name": "ABC",
    "Roles": [
      {
        "RoleID": 1,
        "RoleName": "Admin"
      }
    ]
  }
]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 join 获取嵌套对象数组的 SQL 查询 的相关文章

随机推荐

  • 如何在 PhantomJS 中测试 String.prototype.includes

    我有一个ember cli 0 2 7 using Ember js 1 12 0应用程序的一段代码如下所示 controllers cart js import Ember from ember export default Ember
  • 如何在 git 树的顶部应用补丁以防止重复?

    我正在为一个我认为很简单的问题寻求建议 并且通过创建一个小脚本确实可能很简单 但我认为应该已经有一种方法可以使用 git quilt stgit 来做到这一点 我不太擅长 git 这给我带来了一些问题 我的问题 我有一个 git 树 lin
  • 如何在 NVD3 中突出显示简单折线图上的点?

    我在 NVD3 中有一个像这样的简单折线图http nvd3 org examples line html http nvd3 org examples line html 我想突出显示 例如重叠一个圆圈 我的系列中的一个特定点 给定的 x
  • 在Applet中显示中文文本

    我们有一个可以显示中文文本的Applet 我们为其指定了一种字体 Arial 它在 Windows 和 Mac OSX 下都可以正常工作 但在 Linux 上的 Firefox 中 中文字符呈现为正方形 有办法解决这个问题吗 请注意 我们不
  • HTML5 Canvas - 混合多个translate() 和scale() 调用

    我只是想知道 Canvas 转换是如何工作的 假设我有一个画布 在其内部某处绘制了一个圆圈 并且我想缩放该圆圈 因此它的中心点不会移动 所以我考虑做以下事情 translate circle x circle y scale factor
  • 多维数组初始化

    今天在C 考试中看到一道题 给定数组 int Multi 2 3 2 14 11 13 10 9 6 8 7 1 5 4 2 的价值是什么 Multi 1 1 0 3维数组不应该像这样初始化 如何找到具有此类因数的元素的值 太令人困惑了 您
  • 如何在不使用 Maven 的情况下将 Jacoco 报告与 SonarQube 集成?

    我使用 Jacoco eclipse 插件来测量单元测试覆盖率 并且我能够使用它导出报告 我想将该报告与声纳集成 因此我在项目属性文件中给出了它的路径 我的属性文件如下所示 Required metadata sonar projectKe
  • 将 mysql 表的所有列设置为特定值

    有没有办法一次性将特定记录的 mysql 表的所有列更新为特定值 例如我有一个大约有 70 列的表 它们在创建表时默认设置为 0 当我通过 PHPmyadmin 添加新记录时 只需填写一两个值并提交它 所有其他字段都是设置为 0 但我想将所
  • (java) 写入文件小端

    我正在尝试编写 TIFF IFD 并且正在寻找一种简单的方法来执行以下操作 这段代码显然是错误的 但它表达了我想要的想法 out writeChar 12 bytes 0 1 out writeChar 259 bytes 2 3 out
  • .property() 的作用是什么?在函数(){}.property()中

    Todos TodoController Ember ObjectController extend isCompleted function key value var model this get model if value unde
  • 即使使用 delegate = self,uiwebview 也不会加载请求

    我创建了一个 NSObject 类并包含在 init 中 我创建了一个 uiwebview 将委托设置为 self 并发送加载请求 由于某种原因 webViewDidFinishLoad 或 didFailLoadWithError 永远不
  • 从 Dictionary 迁移到 ConcurrentDictionary,我应该注意哪些常见陷阱?

    我正在考虑从 Dictionary 迁移到 ConcurrentDictionary 以实现多线程环境 具体到我的用例 kvp 通常是
  • 超出内部响应标头大小限制

    当我重定向到相关网站的其他部分时 会发生此错误 return this RedirectToActionPermanent Index Dashboard 在错误发生之前 代码不会单步执行仪表板控制器中的 Index 方法 我认为发布的 F
  • grpc go:如何在服务器端知道客户端何时关闭连接

    我正在使用 grpc go 我有一个 rpc 看起来大致像这样 196 service MyService 197 Operation 1 198 rpc Operation1 OperationRequest returns Operat
  • 将两列添加到 vba 用户窗体组合框

    我有一个用于库存控制的用户表单 用于进出物品 我想做的就是修改下面的代码以在其代码旁边显示每个物品名称以进行搜索物品 代码 Private Sub ComboBox1 Click Dim i As Integer Dim j As Inte
  • 从 http 服务流式传输大文件

    我正在编写一个组件来从 HTTP 服务传输大数据 4 GB 该组件采用 URL 和目标流 目标流可以是文件流 也可以是 POSTS 到不同 HTTP 服务的流 甚至两者都是 作为组件的作者 我需要执行以下步骤直到完成 从 HTTP 流中读取
  • R闪亮制作子面板

    是否有一个简单的解决方案可以使 R 中创建的主选项卡面板中的选项卡面板闪亮 以下是我创建主面板的方法 mainPanel tabsetPanel id tabSelected tabPanel Tab1 uiOutput Tab1 tabP
  • 用于数据存储的 Lua 与 XML

    我们中的许多人都被灌输了使用 XML 来存储数据的观念 它的优点和缺点众所周知 我当然不想在这里讨论它们 然而 在我用 C 编写的项目中 我也使用 Lua 我非常惊讶 Lua 能够如此出色地存储和处理数据 然而 Lua 的这一方面却鲜为人知
  • 在UIPickerView而不是UIView中响应touchesBegan

    我有一个 UIPickerView 在不使用时会淡出至 20 alpha 我希望用户能够触摸选择器并使其淡入 如果我在主视图上放置一个 TouchBegan 方法 我就可以让它工作 但这仅在用户触摸视图时才有效 我尝试对 UIPickerV
  • 使用 join 获取嵌套对象数组的 SQL 查询

    摘要 我将从 JSON 模式开始来描述期望 请注意具有嵌套对象数组的角色 我正在寻找一个可以通过单个查询获取它的 智能查询 id 1 first John roles Expectation gt array of objects id 1