PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tham gia 2 bộ dựa trên thứ tự mặc định

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 trong SELECT 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ới array_lowerarray_upper để mô phỏng generate_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 cho unnest 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 ab :

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);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lỗi:Không thể tạo TypedQuery cho truy vấn có nhiều trả lại

  2. Heroku - ActionView ::Template ::Error (PG ::Error:ERROR:column category_products.desc không tồn tại

  3. Lỗi cú pháp FUNCTION

  4. Nhập một kết xuất postgresql vào Heroku

  5. psql vai trò gây tử vong không tồn tại