Массив агрегата Postgresql
Привет У меня есть две таблицы
Student
--------
Id Name
1 John
2 David
3 Will
Grade
---------
Student_id Mark
1 A
2 B
2 B+
3 C
3 A
Можно ли создать собственный Postgresql для получения таких результатов:
Name Array of marks
-----------------------
'John', {'A'}
'David', {'B','B+'}
'Will', {'C','A'}
Но не, как этот
Name Mark
----------------
'John', 'A'
'David', 'B'
'David', 'B+'
'Will', 'C'
'Will', 'A'
Ответы
Ответ 1
Использовать array_agg: http://www.sqlfiddle.com/#!1/5099e/1
SELECT s.name, array_agg(g.Mark) as marks
FROM student s
LEFT JOIN Grade g ON g.Student_id = s.Id
GROUP BY s.Id
Кстати, если вы используете Postgres 9.1, вам не нужно повторять столбцы в SELECT для GROUP BY, например. вам не нужно повторять имя студента в группе GROUP BY. Вы можете просто GROUP BY на первичном ключе. Если вы удалите первичный ключ на ученике, вам нужно повторить имя студента в группе GROUP BY.
CREATE TABLE grade
(Student_id int, Mark varchar(2));
INSERT INTO grade
(Student_id, Mark)
VALUES
(1, 'A'),
(2, 'B'),
(2, 'B+'),
(3, 'C'),
(3, 'A');
CREATE TABLE student
(Id int primary key, Name varchar(5));
INSERT INTO student
(Id, Name)
VALUES
(1, 'John'),
(2, 'David'),
(3, 'Will');
Ответ 2
Вы можете использовать следующее:
SELECT Student.Name as Name,
(SELECT array(SELECT Mark FROM Grade WHERE Grade.Student_id = Student.Id))
AS ArrayOfMarks
FROM Student
Как описано здесь: http://www.mkyong.com/database/convert-subquery-result-to-array/
Ответ 3
Я понимаю, что вы можете сделать что-то вроде этого:
SELECT p.p_name,
STRING_AGG(Grade.Mark, ',' ORDER BY Grade.Mark) As marks
FROM Student
LEFT JOIN Grade ON Grade.Student_id = Student.Id
GROUP BY Student.Name;
ИЗМЕНИТЬ
Я не уверен. Но может быть, что-то вроде этого:
SELECT p.p_name,
array_to_string(ARRAY_AGG(Grade.Mark),';') As marks
FROM Student
LEFT JOIN Grade ON Grade.Student_id = Student.Id
GROUP BY Student.Name;
Ссылка здесь