Bây giờ, để trả lời thực tế câu hỏi đã được tiết lộ trong các nhận xét, có vẻ như:
Có một số cách để giải quyết vấn đề này:
-
Nếu và chỉ khi các mảng có độ dài bằng nhau, hãy sử dụng nhiều
unnest
các hàm trongSELECT
mệnh đề (một phương pháp không dùng nữa chỉ nên được sử dụng để tương thích ngược); -
Sử dụng
generate_subscripts
để lặp lại các mảng; -
Sử dụng
generate_series
qua các truy vấn phụ đối vớiarray_lower
vàarray_upper
để mô phỏnggenerate_subscripts
nếu bạn cần hỗ trợ các phiên bản quá cũ để cógenerate_subscripts
; -
Dựa vào mệnh lệnh
unnest
trả về bộ giá trị và hy vọng - giống như trong câu trả lời khác của tôi và như được hiển thị bên dưới. Nó sẽ hoạt động, nhưng nó không được đảm bảo sẽ hoạt động trong các phiên bản sau. -
Sử dụng
WITH ORDINALITY
chức năng được thêm vào trong PostgreSQL 9.4 (xem thêm bài đăng đầu tiên của nó ) để lấy số hàng chounnest
khi 9.4 ra mắt. -
Sử dụng nhiều mảng
UNNEST
, là chuẩn SQL nhưng PostgreSQL nào chưa hỗ trợ .
Vì vậy, giả sử chúng ta có hàm arraypair
với các tham số mảng a
và b
:
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
-- blah code here blah
$$ LANGUAGE whatever IMMUTABLE;
và nó được gọi là:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
các định nghĩa hàm khả thi sẽ là:
SRF-in- SELECT
(không dùng nữa)
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
SELECT unnest(a), unnest(b);
$$ LANGUAGE sql IMMUTABLE;
Sẽ tạo ra kết quả kỳ lạ và bất ngờ nếu các mảng không có độ dài bằng nhau; xem tài liệu về các hàm trả về đã đặt và cách sử dụng không chuẩn của chúng trong SELECT
danh sách để tìm hiểu lý do và chính xác điều gì sẽ xảy ra.
generate_subscripts
Đây có thể là lựa chọn an toàn nhất:
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
SELECT
a[i], b[i]
FROM generate_subscripts(CASE WHEN array_length(a,1) >= array_length(b,1) THEN a::text[] ELSE b::text[] END, 1) i;
$$ LANGUAGE sql IMMUTABLE;
Nếu các mảng có độ dài không bằng nhau, như đã viết, nó sẽ trả về các phần tử null cho các mảng ngắn hơn, vì vậy nó hoạt động giống như một phép nối bên ngoài đầy đủ. Đảo ngược ý nghĩa của trường hợp để có được hiệu ứng giống như kết hợp bên trong. Hàm giả sử các mảng là một chiều và chúng bắt đầu ở chỉ số 1. Nếu toàn bộ đối số mảng là NULL thì hàm trả về NULL.
Một phiên bản tổng quát hơn sẽ được viết bằng PL / PgSQL và sẽ kiểm tra array_ndims(a) = 1
, kiểm tra array_lower(a, 1) = 1
, kiểm tra mảng null, v.v. Tôi sẽ giao việc đó cho bạn.
Hy vọng về lợi nhuận theo cặp:
Điều này không được đảm bảo hoạt động, nhưng có với trình thực thi truy vấn hiện tại của PostgreSQL:
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
WITH
rn_c1(rn, col) AS (
SELECT row_number() OVER (), c1.col
FROM unnest(a) c1(col)
),
rn_c2(rn, col) AS (
SELECT row_number() OVER (), c2.col
FROM unnest(b) c2(col)
)
SELECT
rn_c1.col AS c1,
rn_c2.col AS c2
FROM rn_c1
INNER JOIN rn_c2 ON (rn_c1.rn = rn_c2.rn);
$$ LANGUAGE sql IMMUTABLE;
Tôi sẽ cân nhắc sử dụng generate_subscripts
an toàn hơn nhiều.
Đa đối số unnest
:
Điều này nên hoạt động, nhưng không hoạt động vì unnest
của PostgreSQL không chấp nhận nhiều mảng đầu vào (chưa):
SELECT * FROM unnest(a,b);