2012-01-10 50 views
16

Làm thế nào tôi có thể nhận được vị trí của một giá trị trong mảng PostgreSQL? Có phương thức .index() cho hàm Python và array_search() cho PHP, nhưng tôi không thể tìm thấy bất kỳ chức năng nào như vậy cho PostgreSQL. Tôi có nên viết một hàm được lưu trữ để làm điều đó không? Tôi thích giải quyết bằng cách sử dụng chức năng tích hợp sẵn.Tìm vị trí của một giá trị trong mảng PostgreSQL

Trả lời

9

Since version 9.5, có sẵn chức năng: array_position()array_positions(), để tìm kiếm khóa mảng (chỉ lần xuất hiện đầu tiên) hoặc phím (tất cả lần xuất hiện), theo giá trị.

Các chức năng này hỗ trợ loại anyarray.

27

documentation recommends sử dụng chức năng generate_subscripts. Hàm bên dưới của mô phỏng dưới đây là array_search:

CREATE FUNCTION array_search(needle ANYELEMENT, haystack ANYARRAY) 
RETURNS INT AS $$ 
    SELECT i 
     FROM generate_subscripts($2, 1) AS i 
    WHERE $2[i] = $1 
    ORDER BY i 
$$ LANGUAGE sql STABLE; 

Điều này trả về chỉ mục của kết quả đầu tiên, nếu có. Nếu bạn muốn tất cả các kết quả phù hợp, chỉ cần thay đổi RETURNS INT thành RETURNS SETOF INT. Hàm này, như là, trả về NULL nếu không tìm thấy kết quả phù hợp.

Chức năng này chỉ hoạt động với mảng một chiều.

Ngoài ra, hãy nhớ rằng luôn luôn array_search(NULL, a) trả NULL, ngay cả khi mảng chứa các yếu tố null:

> SELECT array_search(null, array[1, 2, null, 4]); 
array_search 
-------------- 

(1 row) 

Điều này là do SQL coi NULL = NULLbiết (ví dụ: NULL). Xem functions-comparison. Nếu bạn muốn array_search để có thể tìm NULL yếu tố, thay đổi

 WHERE $2[i] = $1 

để

 WHERE $2[i] IS NOT DISTINCT FROM $1 
+0

+1 cho generate_subscripts() và câu trả lời rất hoàn chỉnh. –

+2

Câu trả lời hay. Điều này sẽ đơn giản và hiệu quả hơn khi PostgreSQL 9.4 thêm các hàm 'WITH ORDINAL', cho phép bạn chỉ cần viết' unnest (the_array) WITH ORDINAL'. Có lẽ tôi nên viết và gửi một hàm 'idx' đúng cho 9.4, mặc dù ... –

4

Đối với mảng số nguyên chỉ bạn có thể sử dụng rất nhanh idx function from the intarray bundled extension.

Chức năng này chưa được tổng quát hóa để hỗ trợ tất cả các loại mảng, do đó, bạn bị kẹt với phương pháp SQL rất chậm đối với các mảng khác.

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