Как я могу найти сведения о студенте на основе его самой низкой квалификации из списка всех его квалификаций

#sql #postgresql #aggregate-functions

#sql #postgresql #агрегатные функции

Вопрос:

У меня есть 2 таблицы, student и qualifications, как указано ниже. Я должен найти сведения обо всех студентах на основе обязательных полей, и порядок записей должен основываться на его оценках, возрасте, самой высокой квалификации, самой низкой квалификации и проценте его самой низкой квалификации.

Я пробовал разные запросы, в которые я включал все необходимые поля. Но предположим, что если у студента 3 квалификации, записи умножаются столько раз. НАПРИМЕР:

 Sr.No  Student_ID Highest Qualification Marks
1      001         Grad     SSC        80 
2      001         Grad     HSC        60 
3      001         Grad     Grad       80 
4      002         HSC      SSC        60 
5      002         HSC      HSC        50 
6      003         SSC      SSC        40 
  

Это запрос, который я пробовал

 SELECT std.stud_id, std.dob, std.highest_qual, MIN(std.lowest_qual) , std.marks
FROM student std
LEFT JOIN qualifications qual ON std.stud_id = qual.stud_id 
Where std.fees_paid ='Y'
ORDER BY std.marks, std.dob, std.highest_qual
  

Ожидаемый результат:

 001 23-04-1991 Grad SSC 80
002 20-09-1992 HSC  SSC 60
003 13-05-1992 SSC  SSC 40
  

Результат запроса: запрос возвращает все записи вместо одной записи для каждого студента

 001 23-04-1991 Grad SSC 80
001 23-04-1991 Grad HSC 60
001 23-04-1991 Grad GRAD 80
002 20-09-1992 HSC  SSC 60
002 20-09-1992 HSC  HSC 60
003 13-05-1992 SSC  SSC 40
  

Комментарии:

1. Зачем вы объединяете qualifications таблицу, если вы не используете ее в своем запросе?

2. я использовал left join, потому что позже мне, возможно, придется использовать несколько полей, отличных от упомянутых выше, а также включать другое условие

3. И как вы узнаете, какая квалификация выше? max () и min () будут использовать сортировку по алфавиту.

Ответ №1:

Я полагаю, что в вашей qualifications таблице есть какой-то индикатор, указывающий ранг для данной квалификации (скажем qual_rank ). Если это так, вы можете сделать

 select * from
( select s.*, row_number() OVER ( partition by student_id 
       order by q.qual_rank ) as rn
   from student s join qualifications qual ON std.stud_id = qual.stud_id 
) sq where rn = 1;       
  

Если нет, вы должны определить иерархию

 select * from
( select s.*, row_number() OVER ( partition by student_id order by 
                                            CASE qualification WHEN  'SSC'  THEN 1 
                                                               WHEN  'HSC' THEN 2
                                                               WHEN  'Grad' THEN 3
                                                        END 
                                                  ) as rn
from student s) sq where rn = 1; 
  

ДЕМОНСТРАЦИЯ

Комментарии:

1. предположим, что 2-й кандидат обучался на дому и непосредственно имеет свою самую низкую квалификацию в записях как HSC вместо SSC. Будет ли это иметь какое-либо значение для записей?

2. @PrajaktaKalghatgi : Вы пробовали его использовать? Что вы ожидаете увидеть в этом случае SSC или HSC?

3. если самая высокая квалификация — HSC, то HSC должен отображаться для этого студента и SSC для других студентов.

4. @PrajaktaKalghatgi : Это будет работать так, как ожидалось, посмотрите это и запишите результат для student_id 3. Почему бы вам не попробовать и не сообщить мне, если это не сработает?

Ответ №2:

Я бы предположил, что структура таблицы будет такой, и я упомянул запрос для этой структуры.

 CREATE TABLE student(Id integer PRIMARY KEY, Name text);

INSERT INTO student VALUES(1,'Tom');
INSERT INTO student VALUES(2,'Lucy');
INSERT INTO student VALUES(3,'Frank');
INSERT INTO student VALUES(4,'Jane');
INSERT INTO student VALUES(5,'Robert');

CREATE TABLE Qualifications(Id integer PRIMARY KEY, qualification_text text, qualification_level integer);

INSERT INTO Qualifications VALUES(1,'SSC',1);
INSERT INTO Qualifications VALUES(2,'HSC',2);
INSERT INTO Qualifications VALUES(3,'Grad',3);



CREATE TABLE StudentQualifications(student_id integer, qualification_id integer, marks float);

INSERT INTO StudentQualifications VALUES(1,1,80);
INSERT INTO StudentQualifications VALUES(1,2,90);
INSERT INTO StudentQualifications VALUES(1,3,90);
INSERT INTO StudentQualifications VALUES(2,1,75);
INSERT INTO StudentQualifications VALUES(3,1,70);

SELECT result.Name, highest.qualification_text, highest_marks.marks,lowest.qualification_text,lowest_marks.marks FROM
(SELECT Std.name AS Name,Std.Id AS stud_id, MAX(q.qualification_level) AS 
highest,MIN(q.qualification_level) AS lowest
FROM 
student std
LEFT JOIN 
StudentQualifications sq
ON 
std.id = sq.student_id
INNER JOIN
Qualifications q
ON
sq.qualification_id = q.Id
GROUP BY std.Name, std.Id) result
INNER JOIN
Qualifications highest 
ON
highest.qualification_level = result.highest
INNER JOIN
Qualifications lowest
ON
lowest.qualification_level = result.lowest
INNER JOIN
StudentQualifications highest_marks
ON
highest.id = highest_marks.qualification_id
AND
result.stud_id = highest_marks.student_id 
INNER JOIN
StudentQualifications lowest_marks
ON
lowest.id = lowest_marks.qualification_id
AND
result.stud_id = lowest_marks.student_id;
  

Возможно, вам потребуется изменить ВНУТРЕННИЕ СОЕДИНЕНИЯ на ЛЕВЫЕ СОЕДИНЕНИЯ на основе данных и выходных данных, которые вы предпочитаете.

Комментарии:

1. результатом этого запроса будет только самая высокая и самая низкая квалификация. Как я могу получить оценки самой низкой квалификации?

2. Вы можете просто отредактировать последний запрос, чтобы снова объединить с StudentQualifications, чтобы получить оценки:

3. Сейчас я отредактировал ответ. Надеюсь, это сработает для вас