如何加入有很多关系 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