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

Lặp qua các cột của RECORD

Như @Pavel đã giải thích, không chỉ đơn giản là có thể duyệt qua một bản ghi, giống như bạn có thể duyệt qua một mảng. Nhưng có một số cách xung quanh nó - tùy thuộc vào yêu cầu chính xác của bạn. Cuối cùng, vì bạn muốn trả lại tất cả các giá trị trong cùng một cột, bạn cần truyền chúng về cùng một loại - text là điểm chung rõ ràng, bởi vì có một văn bản đại diện cho mọi loại.

Nhanh và bẩn

Giả sử, bạn có một bảng với integer , một text và một date cột.

CREATE TEMP TABLE tbl(a int, b text, c date);
INSERT INTO tbl VALUES
 (1, '1text',     '2012-10-01')
,(2, '2text',     '2012-10-02')
,(3, ',3,ex,',    '2012-10-03')  -- text with commas
,(4, '",4,"ex,"', '2012-10-04')  -- text with commas and double quotes

Sau đó, giải pháp có thể đơn giản như:

SELECT unnest(string_to_array(trim(t::text, '()'), ','))
FROM   tbl t;

Hoạt động cho hai hàng đầu tiên, nhưng không thành công đối với các trường hợp đặc biệt của hàng 3 và 4.
Bạn có thể dễ dàng giải quyết vấn đề bằng dấu phẩy trong biểu diễn văn bản:

SELECT unnest(('{' || trim(t::text, '()') || '}')::text[])
FROM   tbl t
WHERE  a < 4;

Điều này sẽ hoạt động tốt - ngoại trừ dòng 4 có dấu ngoặc kép trong biểu diễn văn bản. Chúng được thoát ra bằng cách nhân đôi chúng lên. Nhưng hàm tạo mảng sẽ cần chúng được thoát bằng \ . Không chắc tại sao lại có sự không tương thích này ...

SELECT ('{' || trim(t::text, '()') || '}') FROM tbl t WHERE a = 4

Lợi nhuận:

{4,""",4,""ex,""",2012-10-04}

Nhưng bạn sẽ cần:

SELECT '{4,"\",4,\"ex,\"",2012-10-04}'::text[];  -- works

Giải pháp thích hợp

Nếu bạn biết trước tên cột, một giải pháp sạch sẽ rất đơn giản:

SELECT unnest(ARRAY[a::text,b::text,c::text])
FROM tbl

Vì bạn hoạt động trên các bản ghi thuộc loại biết rõ, bạn chỉ có thể truy vấn danh mục hệ thống:

SELECT string_agg(a.attname || '::text', ',' ORDER  BY a.attnum)
FROM   pg_catalog.pg_attribute a 
WHERE  a.attrelid = 'tbl'::regclass
AND    a.attnum > 0
AND    a.attisdropped = FALSE

Đặt điều này trong một hàm với SQL động:

CREATE OR REPLACE FUNCTION unnest_table(_tbl text)
  RETURNS SETOF text LANGUAGE plpgsql AS
$func$
BEGIN

RETURN QUERY EXECUTE '
SELECT unnest(ARRAY[' || (
    SELECT string_agg(a.attname || '::text', ',' ORDER  BY a.attnum)
    FROM   pg_catalog.pg_attribute a 
    WHERE  a.attrelid = _tbl::regclass
    AND    a.attnum > 0
    AND    a.attisdropped = false
    ) || '])
FROM   ' || _tbl::regclass;

END
$func$;

Gọi:

SELECT unnest_table('tbl') AS val

Lợi nhuận:

val
-----
1
1text
2012-10-01
2
2text
2012-10-02
3
,3,ex,
2012-10-03
4
",4,"ex,"
2012-10-04

Điều này hoạt động mà không cần cài đặt các mô-đun bổ sung. Một tùy chọn khác là cài đặt tiện ích mở rộng hstore và sử dụng nó như @Craig demo.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tổng quan về các phương pháp quét khác nhau trong PostgreSQL

  2. Hiểu và đọc Danh mục hệ thống PostgreSQL

  3. SQL chọn các phần tử trong đó tổng trường nhỏ hơn N

  4. Đếm tổng tích lũy trong Postgresql

  5. ĐẶT HÀNG tùy chỉnh theo giải thích