2010-04-01 36 views
169

Tôi có một bảng và tôi muốn kéo một hàng cho mỗi id với các giá trị trường nối.Postgresql GROUP_CONCAT tương đương?

Trong bàn của tôi, ví dụ, tôi có điều này:

TM67 | 4 | 32556 
TM67 | 9 | 98200 
TM67 | 72 | 22300 
TM99 | 2 | 23009 
TM99 | 3 | 11200 

Và tôi muốn đầu ra:

TM67 | 4,9,72 | 32556,98200,22300 
TM99 | 2,3 | 23009,11200 

Trong MySQL tôi đã có thể sử dụng chức năng tổng hợp GROUP_CONCAT, nhưng dường như không hoạt động ở đây ... Có tương đương với PostgreSQL hay cách khác để thực hiện điều này?

+0

Không phải là câu trả lời, nhưng hãy kiểm tra http://www.postgresonline.com/journal/index.php? /archives/14-CrossTab-Queries-in-PostgreSQL-using-tablefunc-contrib.html. – Kuberchaun

+1

http://stackoverflow.com/questions/1943433/postgresql-concat-ws-like-function –

+0

có thể trùng lặp của [Mô phỏng nhóm \ _concat chức năng MySQL trong SQL Server?] (Http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-sql-server) – ntalbs

Trả lời

155

Đây có lẽ là một điểm khởi đầu tốt (phiên bản 8.4+ chỉ):

SELECT id_field, array_agg(value_field1), array_agg(value_field2) 
FROM data_table 
GROUP BY id_field 

array_agg trả về một mảng, nhưng bạn có thể CAST rằng văn bản và chỉnh sửa khi cần thiết (xem giải thích, dưới đây).

Trước khi phiên bản 8.4, bạn phải xác định điều đó cho mình trước khi sử dụng:

CREATE AGGREGATE array_agg (anyelement) 
(
    sfunc = array_append, 
    stype = anyarray, 
    initcond = '{}' 
); 

(diễn giải từ các tài liệu PostgreSQL)

Làm rõ:

  • Kết quả của việc đúc một mảng thành văn bản là chuỗi kết quả bắt đầu và kết thúc bằng dấu ngoặc nhọn. Những niềng răng cần phải được loại bỏ bằng một số phương pháp, nếu họ không mong muốn.
  • Đúc ANYARRAY thành TEXT mô phỏng tốt nhất đầu ra CSV vì các phần tử chứa dấu phẩy được nhúng kép ở đầu ra theo kiểu CSV chuẩn. Không phải mảng array_to_string() hoặc string_agg() (chuỗi "group_concat" được thêm vào trong 9.1) với dấu phẩy được nhúng, dẫn đến số lượng phần tử không chính xác trong danh sách kết quả.
  • Chức năng 9.1 string_agg() mới KHÔNG đưa kết quả bên trong vào TEXT trước. Vì vậy, "string_agg (value_field)" sẽ tạo ra một lỗi nếu value_field là một số nguyên. "string_agg (value_field :: text)" sẽ được yêu cầu. Phương thức array_agg() chỉ yêu cầu một diễn viên sau khi tập hợp (chứ không phải là một phép tính cho mỗi giá trị).
+0

Và trong 9.0 bạn sẽ có listagg() –

+4

Để nhận CSV truy vấn nên là: SELECT id_field, array_to_string (mảng_agg (value_field1), ','), array_to_string (mảng_agg (value_field2), ',') FROM data_table GROUP BY id_field – Nux

+2

Bạn không thể sử dụng array_to_string trong mọi trường hợp tại đây. Nếu value_field của bạn chứa dấu phẩy được nhúng, CSV kết quả là không chính xác. Việc sử dụng array_agg() và truyền tới TEXT sẽ trích dẫn đúng các chuỗi bằng dấu phẩy được nhúng. Các chỉ báo trước là nó cũng bao gồm các dấu ngoặc nhọn bắt đầu và kết thúc, do đó tuyên bố của tôi "và chỉnh sửa khi cần thiết". Tôi sẽ chỉnh sửa để làm rõ điểm đó. –

30
SELECT array_to_string(array(SELECT a FROM b),', '); 

sẽ làm tốt.

+4

Điều này cũng hoạt động trước 9.0 - đã thử nghiệm nó với 8.4. 5 – chrpes

+0

Excelent !!! Làm việc cho tôi. Teste cũng Postgres 8.3.6. Xe tăng! – vandersondf

+0

Có thể làm điều gì đó giống như trong [bình luận này] (http://stackoverflow.com/questions/2560946/postgresql-group-concat-equivalent#comment23843695_8803563), nơi bạn tập hợp theo một thứ tự nhất định? Làm thế nào bạn sẽ xử lý nhóm theo một cột và đặt hàng bởi một cột khác (ví dụ, để nối các biến trong một tập dữ liệu theo chiều dọc)? –

178

Since 9.0 này thậm chí còn dễ dàng hơn:

SELECT id, 
     string_agg(some_column, ',') 
FROM the_table 
GROUP BY id 
+18

Lưu ý rằng cú pháp cũng cho phép bạn chỉ định thứ tự các giá trị trong chuỗi (hoặc mảng, sử dụng 'mảng_agg'), ví dụ: 'string_agg (some_column, ',' ORDER BY some_column)' hoặc thậm chí 'string_agg (họ || ',' || tên, ';' ORDER BY họ, tên)' – IMSoP

+0

@a_horse_with_no_name Tôi thấy rất nhiều bài viết hay của bạn SO trong khi tôi đang làm việc trên các vấn đề Postgres khác nhau. Tôi không thấy cách liên hệ với bạn trong tiểu sử của bạn. Bạn có mở để giao tiếp/làm việc trên các dự án bên ngoài SO không? Xin lỗi vì đã ping bạn qua bình luận nếu không. Nếu bạn mở để có thể cộng tác/làm việc bên ngoài SO, bạn có thể liên hệ với tôi từ hồ sơ của tôi nếu vậy: http://stackoverflow.com/users/2565593/steve-midgley - Bạn đang làm công việc tuyệt vời ở đây - cảm ơn bạn ! (Và với các biên tập viên, tôi dựa vào các ý kiến ​​meta như thế này để lại bình luận này: http://meta.stackexchange.com/a/58715/278168) –

8

Hãy thử như thế này:

select field1, array_to_string(array_agg(field2), ',') 
from table1 
group by field1; 
Các vấn đề liên quan