PostgreSQL聚合数组


94

嗨,我有两个桌子

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'

Answers:


161

使用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
噢,我的上帝,非常感谢您对选择/分组的评论,太棒了!真烦人!
mrbrdo

8

据我了解,您可以执行以下操作:

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;

这里参考


我认为他想要的是pgsql数组,而不是逗号分隔的字符串
ThiefMaster 2012年


0

@迈克尔·布恩说对了。我使用array_agg获得了所需的东西。

这里只是一个基本的查询示例,以防有人帮助:

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

结果是:

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


这篇文章对我也有很多帮助:SQL和Python Pandas中的“分组依据”。基本上说,仅在可能的情况下使用SQL更为方便,但是Python Pandas对于在过滤过程中实现额外的功能很有用。

希望对您有所帮助

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.