Postgresql-Aggregatarray

94

Hallo, ich habe zwei Tische

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

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

Ist es möglich, native Postgresql auszuwählen, um Ergebnisse wie diese zu erhalten:

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

Aber nicht so

Name    Mark
----------------
'John',     'A'
'David',    'B'
'David',    'B+'
'Will',     'C'
'Will',     'A'
Eazy
quelle

Antworten:

161

Verwenden Sie 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

By the way, wenn Sie Postgres verwenden 9.1, Sie brauchen sich nicht wiederholen Sie die Spalten auf SELECT GROUP BY, zB Sie nicht über die Schülernamen auf GROUP BY wiederholen müssen. Sie können lediglich nach Primärschlüssel gruppieren. Wenn Sie den Primärschlüssel für Schüler entfernen, müssen Sie den Schülernamen in GROUP BY wiederholen.

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
quelle
2
Oh mein Gott, vielen Dank für deine Bemerkung zu select / group, das ist so großartig! Das war echt nervig!
Mrbrdo
8

Was ich verstehe, können Sie so etwas tun:

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;

BEARBEITEN

Ich bin nicht sicher. Aber vielleicht so etwas dann:

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;

Referenz hier

Arion
quelle
Ich denke, er will ein pgsql-Array, keine durch Kommas getrennte Zeichenfolge
ThiefMaster
0

@ Michael Buen hat es richtig gemacht. Mit array_agg habe ich bekommen, was ich brauchte.

Hier nur ein einfaches Abfragebeispiel für den Fall, dass es jemandem hilft:

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

Und das Ergebnis war so etwas wie:

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


Dieser Beitrag hat mir auch sehr geholfen: "Gruppieren nach" in SQL und Python Pandas . Grundsätzlich heißt es, dass es bequemer ist, wenn möglich nur SQL zu verwenden, Python-Pandas jedoch nützlich sein können, um zusätzliche Funktionen im Filterprozess zu erreichen.

Ich hoffe, es hilft

Javi
quelle