简体   繁体   English

高效查询以联接三个表

[英]Efficient query to join three tables

My app has a users table, a teams table, a teams_users table, and an assessments table. 我的应用程序有一个users表,一个teams表,一个teams_users表和一个assessments表。 Oversimplified: 简单化:

**users**
id

**teams**
id

**teams_users**
team_id
user_id

**assessments**
id
user_id
team_id

A user can have many assessments. 用户可以进行许多评估。

When I grab users in a certain context, I want to grab their associated assessments as well (the whole object), plus, as a value on the returned user, the team_ids which are essentially the result of plucking the team_id column for all rows in the teams_users table with the user's user_id . 当我在特定上下文中获取用户时,我也希望获取其关联的评估(整个对象),再加上返回的用户的值,即team_ids ,这实际上是针对其中所有行都拔除了team_id列的结果带用户的user_idteams_users表。

I know how to do each of these queries separately, but I'm unsure of how much I can combine into one efficient query, and even more unsure how to do that, as I'm pretty rusty with SQL. 我知道如何分别执行每个查询,但是我不确定我可以组合成一个有效查询的数量,甚至不确定如何执行该操作,因为我对SQL相当不了解。 My first thought was something like this: 我的第一个想法是这样的:

SELECT users.id, users.name, users.email, users.role
FROM users
INNER JOIN assessments ON assessments.user_id = users.id
WHERE users.id='someID'

In that query, though, I'm not actually doing anything with the assessments. 但是,在该查询中,我实际上并未对评估做任何事情。 So I was considering something like this: 所以我在考虑这样的事情:

SELECT users.id, users.name, users.email, users.role, assessments
FROM users
INNER JOIN assessments ON assessments.user_id = users.id
WHERE users.id='someID'

This SORT of works, but returns the assessments as a parenthesis-delimited array of values (I'm using JavaScript, and the pg library otherwise parses responses into JSON), which it seems better to fix on a SQL level than to parse into JSON: 这种SORT的工作原理是,但将评估返回为括号分隔的值数组(我正在使用JavaScript,而pg库则将响应解析为JSON),在SQL级别进行修复比将其解析为JSON似乎更好。 :

{
    id: 'mEPRVHp3',
    name: 'Frank',
    role: 'admin',
    assessments: '(uibbH0ff,rPWZDIoA,mEPRVHp3,99,2017-12-01)' 
}

To clarify, I'd prefer it like so: 为了澄清,我更喜欢这样:

{
    id: 'mEPRVHp3',
    name: 'Frank',
    role: 'admin',
    assessments: [
     { 
       id: 'uibbH0ff',
       team_id: 'rPWZDIoA',
       user_id: 'mEPRVHp3',
       score: 99,
       date: '2017-12-01'
     }
   ]
}

Then separately, I'd love to grab the teams_users team_id s in the same query. 然后,我想分别在同一查询中获取teams_users team_id So that the end response is something like this: 这样最终响应是这样的:

{
    id: 'mEPRVHp3',
    name: 'Frank',
    role: 'admin',
    assessments: [
     { 
       id: 'uibbH0ff',
       team_id: 'rPWZDIoA',
       user_id: 'mEPRVHp3',
       score: 99,
       date: '2017-12-01'
     }
   ],
   team_ids: ['rPWZDIoA']
}

Tried to add teams_users.team_id AS team_ids to the end of the SELECT statement, but that broke the whole query. 试图在SELECT语句的末尾添加teams_users.team_id AS team_ids ,但这破坏了整个查询。

Again, not sure if that's possible, and in this case, not at ALL sure how to do it. 再次,不确定是否可行,在这种情况下,完全不确定如何执行。

Any thoughts? 有什么想法吗? Working on my limited SQL skillz. 使用有限的SQL技能。

Thanks! 谢谢!

Assuming you are using PostgreSQL version 9.3 or newer. 假设您使用的是PostgreSQL 9.3或更高版本。

I would use row_to_json() to "format" the assessment record. 我将使用row_to_json()来“格式化”评估记录。 Then I would use a lateral join to get your team ids. 然后,我将使用横向联接来获取您的团队ID。

Like so: 像这样:

SELECT
    usr.id,
    usr.name, 
    usr.email,
    usr.role,
    row_to_json(asmnt) AS assessments, --Use row_to_json()
    tusr.team_ids
FROM
    users usr
INNER JOIN
    assessments asmnt
    ON asmnt.user_id = usr.id
INNER JOIN LATERAL
    (
    SELECT
        array_agg(teams_users.team_id) AS team_ids
    FROM
        teams_users
    WHERE
        teams_users.user_id = usr.id
    ) tusr
    ON TRUE
WHERE
    usr.id = 'someID';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM