Postgresql aggregate array


94

Ciao ho due tavoli

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

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

È possibile selezionare Postgresql nativo per ottenere risultati come questo:

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

Ma non così

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

Risposte:


161

Usa 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

A proposito, se stai usando Postgres 9.1, non è necessario ripetere le colonne da SELEZIONA a GRUPPO BY, ad esempio non è necessario ripetere il nome dello studente in GRUPPO BY. Puoi semplicemente GROUP BY sulla chiave primaria. Se rimuovi la chiave primaria sullo studente, devi ripetere il nome dello studente su 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
Oh mio dio, grazie mille per il tuo commento su select / group, è fantastico! È stato davvero fastidioso!
mrbrdo

8

Quello che ho capito puoi fare qualcosa del genere:

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;

MODIFICARE

Non sono sicuro. Ma forse qualcosa del genere allora:

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;

Riferimento qui


Penso che voglia un array pgsql, non una stringa separata da virgole
ThiefMaster


0

@Michael Buen ha capito bene. Ho ottenuto ciò di cui avevo bisogno usando array_agg.

Ecco solo un esempio di query di base nel caso in cui aiuti qualcuno:

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

E il risultato è stato qualcosa di simile:

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


Anche questo post mi ha aiutato molto: "Group By" in SQL e Python Pandas . Fondamentalmente dice che è più conveniente usare solo SQL quando possibile, ma che Python Pandas può essere utile per ottenere funzionalità extra nel processo di filtraggio.

spero possa essere d'aiuto

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.