อาร์เรย์รวม Postgresql


97

ฉันมีโต๊ะสองตัว

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

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

เป็นไปได้หรือไม่ที่จะสร้าง Postgresql SELECT เพื่อให้ได้ผลลัพธ์ดังนี้:

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

แต่ไม่เหมือนข้างล่าง

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

คำตอบ:


168

ใช้ 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

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


0

@ Michael Buen เข้าใจถูกแล้ว ฉันได้สิ่งที่ต้องการโดยใช้ 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 นุ่น โดยพื้นฐานแล้วบอกว่าสะดวกกว่าที่จะใช้เฉพาะ SQL เมื่อเป็นไปได้ แต่ Python Pandas จะมีประโยชน์ในการบรรลุฟังก์ชันพิเศษในกระบวนการกรอง

ฉันหวังว่ามันจะช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.