How to join has many relation table and fetch result by type

做~自己de王妃 提交于 2019-12-13 03:38:53

问题


I have a few tables which I am trying to join and fetch the results for a list

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    |
+--------------+------------+-------+

I need to fetch the result of average ratings for each interview given in the following manner.

+--------------+--------------+-----------------+-----------------+
| interview_id | System Rating|Recruiter Rating |Candidate Rating |
+--------------+--------------+-----------------+-----------------+
|            1 | 4.3          |  5              |   4             |
|            2 | 4.0          |  0              |   4             |
|            3 | 4.6          |  0              |   0             |
+--------------+--------------+-----------------+-----------------+

Each interview can will have one 1 candidate rating and 1 recruiter rating but that is optional. If given a record is created in participant rating with rating and type.

Need to get the average of system ratings of all the types and get one value as system rating and if rating provided by participants then display else display as 0 if any or both the participants not provided any rating.

Please ignore the values, if there is a mistake.

The SQL which I tried to get the result.

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

The problem is whenever participant ratings are not present then results are missing as there is join.


回答1:


Use LEFT JOIN to make sure if relation tables do not have any data, still we can have records from the main table.

Reference: Understanding MySQL LEFT JOIN

Issue(s):

  • Wrong field name: pr.interview_id = i.interview_id, it should be pr.interview_id = i.id as we don't have any interview_id field in interviews table, it would be id field - based on your query.
  • pr.interview_id = i.id in where clause: If participant_rating table does not have any records for a given interview, this will cause the removal of that interview from the result set. Use LEFT JOIN for participant_rating table.
  • sr.interview_id = i.id in where clause: If system_rating table does not have any records for a given interview, this will cause the removal of that interview from the result set. Use LEFT JOIN for system_rating table too.
  • Usage of AVG works but won't work for other aggregates functions like SUM, COUNT.. because if we have one to many relationships then join will make there will be multiple records for the same row.

Solution:

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


来源:https://stackoverflow.com/questions/57890951/how-to-join-has-many-relation-table-and-fetch-result-by-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!