如何加入有很多关系 table 并按类型获取结果
How to join has many relation table and fetch result by type
我有几个表,我正在尝试加入这些表并获取列表的结果
Interviews Table
+--------------+-----------+
| interview_id | Candidate |
+--------------+-----------+
| 1 | Ram |
| 2 | Rahim |
| 3 | Joseph |
+--------------+-----------+
Participant Ratings Table
+--------------+-----------+-------+
| interview_id | Rater Type|Rating |
+--------------+-----------+-------+
| 1 | Candidate | 4 |
| 2 | Candidate | 4 |
| 1 | Recruiter | 5 |
+--------------+-----------+-------+
System Ratings Table
+--------------+------------+-------+
| interview_id | Rating Type|Rating |
+--------------+------------+-------+
| 1 | Quality | 4 |
| 1 | Depth | 4 |
| 1 | Accuracy | 5 |
| 2 | Quality | 4 |
| 2 | Depth | 3 |
| 2 | Accuracy | 5 |
| 3 | Quality | 4 |
| 3 | Depth | 5 |
| 3 | Accuracy | 5 |
+--------------+------------+-------+
我需要按以下方式获取每次面试的平均评分结果。
+--------------+--------------+-----------------+-----------------+
| interview_id | System Rating|Recruiter Rating |Candidate Rating |
+--------------+--------------+-----------------+-----------------+
| 1 | 4.3 | 5 | 4 |
| 2 | 4.0 | 0 | 4 |
| 3 | 4.6 | 0 | 0 |
+--------------+--------------+-----------------+-----------------+
每次面试都可以有 1 个候选人评级和 1 个招聘人员评级,但这是可选的。如果给定,则会在参与者评分中创建一条记录,其中包含评分和类型。
需要获取所有类型的系统评分的平均值,并获得一个值作为系统评分,如果参与者提供评分则显示,否则如果任何参与者或两个参与者均未提供任何评分,则显示为 0。
如果有错误,请忽略这些值。
我尝试得到的结果SQL
SELECT i.candidate, i.id AS interview_id,
AVG(sr.rating) AS system_rating,
AVG(CASE WHEN pr.rater_type = 'Candidate' THEN pr.rating END) AS candidate_rating,
AVG(CASE WHEN pr.rater_type = 'Recruiter' THEN pr.rating END) AS recruiter_rating
FROM system_ratings sr, participant_ratings pr, interviews i
WHERE sr.interview_id = i.id AND i.id = 2497 AND pr.interview_id = i.interview_id
问题是,只要参与者评分不存在,结果就会丢失,因为有加入。
使用LEFT JOIN
来确保如果关系table没有任何数据,我们仍然可以从主table.
中获得记录
参考:Understanding MySQL LEFT JOIN
问题:
- 错误的字段名称:
pr.interview_id = i.interview_id
,应该是pr.interview_id = i.id
因为我们在[=14中没有任何interview_id字段=] table,它将是 id
字段 - 根据您的查询。
pr.interview_id = i.id
in where
clause: 如果 participant_rating
table 没有给定采访的任何记录,这将导致从结果集中删除该采访。 LEFT JOIN
用于 participant_rating
table.
sr.interview_id = i.id
in where
clause: 如果 system_rating
table 没有给定采访的任何记录,这将导致从结果集中删除该采访。 LEFT JOIN
也用于 system_rating
table。
Usage of AVG
有效,但不适用于其他聚合函数,如 SUM, COUNT
.. 因为如果我们有一对多关系,那么 join 将使同一行有多个记录。
解决方法:
SELECT
i.id AS interview_id,
i.candidate,
AVG(sr.rating) AS system_rating,
AVG(CASE WHEN pr.rater_type = 'Candidate' THEN pr.rating END) AS candidate_rating,
AVG(CASE WHEN pr.rater_type = 'Recruiter' THEN pr.rating END) AS recruiter_rating
FROM interviews i
LEFT JOIN system_rating sr ON sr.interview_id = i.id
LEFT JOIN participant_rating pr ON pr.interview_id = i.id
-- WHERE i.id IN (1, 2, 3) -- use whenever required
GROUP BY i.id
我有几个表,我正在尝试加入这些表并获取列表的结果
Interviews Table
+--------------+-----------+
| interview_id | Candidate |
+--------------+-----------+
| 1 | Ram |
| 2 | Rahim |
| 3 | Joseph |
+--------------+-----------+
Participant Ratings Table
+--------------+-----------+-------+
| interview_id | Rater Type|Rating |
+--------------+-----------+-------+
| 1 | Candidate | 4 |
| 2 | Candidate | 4 |
| 1 | Recruiter | 5 |
+--------------+-----------+-------+
System Ratings Table
+--------------+------------+-------+
| interview_id | Rating Type|Rating |
+--------------+------------+-------+
| 1 | Quality | 4 |
| 1 | Depth | 4 |
| 1 | Accuracy | 5 |
| 2 | Quality | 4 |
| 2 | Depth | 3 |
| 2 | Accuracy | 5 |
| 3 | Quality | 4 |
| 3 | Depth | 5 |
| 3 | Accuracy | 5 |
+--------------+------------+-------+
我需要按以下方式获取每次面试的平均评分结果。
+--------------+--------------+-----------------+-----------------+
| interview_id | System Rating|Recruiter Rating |Candidate Rating |
+--------------+--------------+-----------------+-----------------+
| 1 | 4.3 | 5 | 4 |
| 2 | 4.0 | 0 | 4 |
| 3 | 4.6 | 0 | 0 |
+--------------+--------------+-----------------+-----------------+
每次面试都可以有 1 个候选人评级和 1 个招聘人员评级,但这是可选的。如果给定,则会在参与者评分中创建一条记录,其中包含评分和类型。
需要获取所有类型的系统评分的平均值,并获得一个值作为系统评分,如果参与者提供评分则显示,否则如果任何参与者或两个参与者均未提供任何评分,则显示为 0。
如果有错误,请忽略这些值。
我尝试得到的结果SQL
SELECT i.candidate, i.id AS interview_id,
AVG(sr.rating) AS system_rating,
AVG(CASE WHEN pr.rater_type = 'Candidate' THEN pr.rating END) AS candidate_rating,
AVG(CASE WHEN pr.rater_type = 'Recruiter' THEN pr.rating END) AS recruiter_rating
FROM system_ratings sr, participant_ratings pr, interviews i
WHERE sr.interview_id = i.id AND i.id = 2497 AND pr.interview_id = i.interview_id
问题是,只要参与者评分不存在,结果就会丢失,因为有加入。
使用LEFT JOIN
来确保如果关系table没有任何数据,我们仍然可以从主table.
参考:Understanding MySQL LEFT JOIN
问题:
- 错误的字段名称:
pr.interview_id = i.interview_id
,应该是pr.interview_id = i.id
因为我们在[=14中没有任何interview_id字段=] table,它将是id
字段 - 根据您的查询。 pr.interview_id = i.id
inwhere
clause: 如果participant_rating
table 没有给定采访的任何记录,这将导致从结果集中删除该采访。LEFT JOIN
用于participant_rating
table.sr.interview_id = i.id
inwhere
clause: 如果system_rating
table 没有给定采访的任何记录,这将导致从结果集中删除该采访。LEFT JOIN
也用于system_rating
table。Usage of AVG
有效,但不适用于其他聚合函数,如SUM, COUNT
.. 因为如果我们有一对多关系,那么 join 将使同一行有多个记录。
解决方法:
SELECT
i.id AS interview_id,
i.candidate,
AVG(sr.rating) AS system_rating,
AVG(CASE WHEN pr.rater_type = 'Candidate' THEN pr.rating END) AS candidate_rating,
AVG(CASE WHEN pr.rater_type = 'Recruiter' THEN pr.rating END) AS recruiter_rating
FROM interviews i
LEFT JOIN system_rating sr ON sr.interview_id = i.id
LEFT JOIN participant_rating pr ON pr.interview_id = i.id
-- WHERE i.id IN (1, 2, 3) -- use whenever required
GROUP BY i.id