2013-03-02 53 views
10

Tôi sử dụng postgreSQL 9.1. Trong cơ sở dữ liệu của tôi có một bảng trông giống nhưPostgreSQL không cần thiết với mảng trống

id | ... | values 
----------------------- 
1 | ... | {1,2,3} 
2 | ... | {} 

trong đó id là một số nguyên và giá trị là một mảng nguyên. Các mảng có thể trống.

Tôi cần phải không cần danh sách này. Nếu tôi truy vấn

select id, ..., unnest(values) 
from table 

tôi nhận được ba hàng cho id = 1 (như mong đợi) và không có đường cho id = 2. Có cách nào để có được một kết quả như

id | ... | unnest 
------------------- 
1 | ... | 1 
1 | ... | 2 
1 | ... | 3 
2 | ... | null 

tức là một truy vấn mà cũng chứa các dòng có một mảng trống?

Trả lời

9
select id, 
     case 
     when int_values is null or array_length(int_values,1) is null then null 
     else unnest(int_values) 
     end as value 
from the_table; 

(lưu ý rằng tôi đổi tên cột values-int_values như values là một từ dành riêng và không nên được sử dụng như một tên cột).

SQLFiddle: http://sqlfiddle.com/#!1/a0bb4/1


Postgres 10 không cho phép sử dụng unnest() như thế nữa.

Bạn cần phải sử dụng một bên tham gia:

select id, t.i 
from the_table 
    cross join lateral unnest(coalesce(nullif(int_values,'{}'),array[null::int])) as t(i); 

dụ Online: http://rextester.com/ALNX23313

+0

điều này sẽ không hoạt động trên Postgresql 10 –

+0

@BleedingFingers: xem cập nhật của tôi –

0

Bạn sẽ cần phải sử dụng tự LEFT JOIN, như thế này (cũng trên SQL Fiddle):

SELECT t.id, u.u 
    FROM tab t 
    LEFT JOIN (SELECT id, unnest(vals) u FROM tab) u 
    USING (id); 

Note, mà cho các bảng lớn hơn truy vấn sẽ được thực hiện tồi tệ.

1
select id, 
    unnest (
     "values" 
     || 
     (array[null]::integer[])[1:(array_upper("values", 1) is null)::integer] 
    ) 
from "table" 
3

Sau khi xem xét lại vấn đề này, nó đánh tôi rằng điều này có thể đơn giản hơn và nhanh hơn.
Đảo ngược logic của currently accepted solution by @a_horse:

SELECT id, CASE WHEN values <> '{}' THEN unnest(values) END AS value 
FROM tbl 
  • này trả về một hàng với NULL trong value cho một mảng trống cũng như cho một mảng NULL, bởi vì chỉ có một mảng với các yếu tố trong nó tạo ra TRUE trong thử nghiệm values <> '{}'.

  • Làm việc cho các mảng bất kỳ loại nào, vì chữ '{}' được tự động ép buộc thành loại đối sánh.

  • Nếu không có chi tiết rõ ràng ELSE chi nhánh, CASE trả về NULL, đó là những gì chúng tôi muốn.

  • Mảng có các thành phần NULL sẽ trả về các hàng bất kể.
    Tuy nhiên. tôi thấy một sự bất thường đó và đăng một câu hỏi liên quan đến rằng:

    Hóa ra là một lỗi đã được cố định sau khi báo cáo của tôi cho pg 9.3+.

Các vấn đề liên quan