[英]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_id
的teams_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.