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
unnestcác hàm trongSELECTmệ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_seriesqua các truy vấn phụ đối vớiarray_lowervàarray_upperđể mô phỏnggenerate_subscriptsnế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
unnesttrả 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 ORDINALITYchứ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 chounnestkhi 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);