Postgresql toplama dizisi


97

İki masam var

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

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

Aşağıdaki gibi sonuçlar almak için yerel Postgresql SELECT yapmak mümkün mü:

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

Ama aşağıdaki gibi değil

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

Yanıtlar:


168

Array_agg kullanın: 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

Bu arada, Postgres 9.1 kullanıyorsanız , SELECT to GROUP BY üzerindeki sütunları tekrarlamanıza gerek yoktur, örneğin GROUP BY üzerinde öğrenci ismini tekrarlamanıza gerek yoktur. Yalnızca birincil anahtarda GRUPLAMA yapabilirsiniz. Öğrenci üzerindeki birincil anahtarı kaldırırsanız, öğrenci adını GROUP BY üzerinde tekrarlamanız gerekir.

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
Aman tanrım, seçme / grup hakkındaki yorumunuz için çok teşekkür ederim, bu harika! Bu gerçekten can sıkıcıydı!
mrbrdo

8

Anladığım kadarıyla böyle bir şey yapabilirsiniz:

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;

DÜZENLE

Emin değilim. Ama belki böyle bir şey o zaman:

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;

Referans burada


Onun bir pgsql dizi değil, bir virgülle ayrılmış dize istiyor
ThiefMaster


0

@Michael Buen doğru anladı. Array_agg kullanarak ihtiyacım olanı aldım.

İşte birisine yardımcı olması durumunda basit bir sorgu örneği:

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

Ve sonuç şöyle bir şeydi:

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


Bu gönderi bana çok yardımcı oldu: SQL ve Python Pandas'ta "Group By" . Temel olarak, mümkün olduğunda yalnızca SQL kullanmanın daha uygun olduğunu, ancak Python Pandas'ın filtreleme işleminde ekstra işlevler elde etmek için yararlı olabileceğini söylüyor.

Umut ediyorum bu yardım eder

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.