Array agregat postgresql

95

Hai, saya punya dua tabel

Student
--------
Id  Name
1   John    
2   David
3   Will

Grade
---------
Student_id  Mark
1           A
2           B
2           B+
3           C
3           A

Apakah mungkin membuat pilihan Postgresql asli untuk mendapatkan hasil seperti ini:

Name    Array of marks
-----------------------
'John',     {'A'}
'David',    {'B','B+'}
'Will',     {'C','A'}

Tapi tidak seperti ini

Name    Mark
----------------
'John',     'A'
'David',    'B'
'David',    'B+'
'Will',     'C'
'Will',     'A'
mudah
sumber

Jawaban:

163

Gunakan 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

Ngomong-ngomong, jika Anda menggunakan Postgres 9.1, Anda tidak perlu mengulang kolom di SELECT to GROUP BY, misalnya Anda tidak perlu mengulang nama siswa di GROUP BY. Anda hanya dapat MENGELOMPOKKAN OLEH pada kunci utama. Jika Anda menghapus kunci utama pada siswa, Anda perlu mengulangi nama siswa di 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');
Michael Buen
sumber
2
Ya Tuhan, terima kasih banyak atas komentar Anda tentang pilih / grup, itu sangat luar biasa! Itu sangat menyebalkan!
mrbrdo
8

Yang saya mengerti Anda bisa melakukan sesuatu seperti ini:

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;

EDIT

Saya tidak yakin. Tapi mungkin sesuatu seperti ini:

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;

Referensi di sini

Arion
sumber
Saya pikir dia menginginkan array pgsql, bukan string yang dipisahkan koma
ThiefMaster
0

@Ichael Buen melakukannya dengan benar. Saya mendapatkan apa yang saya butuhkan menggunakan array_agg.

Di sini hanya contoh kueri dasar jika itu membantu seseorang:

SELECT directory, ARRAY_AGG(file_name) FROM table WHERE type = 'ZIP' GROUP BY directory;

Dan hasilnya seperti ini:

parent_directory | array_agg | ------------------------+----------------------------------------+ /home/postgresql/files | {zip_1.zip,zip_2.zip,zip_3.zip} | /home/postgresql/files2 | {file1.zip,file2.zip} |


Posting ini juga banyak membantu saya: "Group By" di SQL dan Python Pandas . Ini pada dasarnya mengatakan bahwa lebih mudah menggunakan hanya SQL jika memungkinkan, tetapi Python Pandas dapat berguna untuk mencapai fungsionalitas tambahan dalam proses pemfilteran.

Saya harap ini membantu

Javi
sumber