9.4 या बाद के संस्करण पोस्ट करें
WITH ORDINALITY
का उपयोग करें सेट-रिटर्निंग फ़ंक्शंस के लिए:
जब FROM
. में कोई फ़ंक्शन क्लॉज WITH ORDINALITY
द्वारा प्रत्यय दिया गया है , एbigint
कॉलम को आउटपुट में जोड़ा जाता है जो 1 से शुरू होता है और फ़ंक्शन के आउटपुट की प्रत्येक पंक्ति के लिए 1 से वृद्धि करता है। यह unnest()
. जैसे सेट रिटर्निंग फ़ंक्शंस के मामले में सबसे उपयोगी है ।
LATERAL
. के संयोजन में पीजी 9.3+ में फीचर, और pgsql-hackers पर इस थ्रेड के अनुसार, उपरोक्त क्वेरी को अब इस प्रकार लिखा जा सकता है:
SELECT t.id, a.elem, a.nr
FROM tbl AS t
LEFT JOIN LATERAL unnest(string_to_array(t.elements, ','))
WITH ORDINALITY AS a(elem, nr) ON TRUE;
LEFT JOIN ... ON TRUE
बाईं तालिका में सभी पंक्तियों को संरक्षित करता है, भले ही दाईं ओर तालिका अभिव्यक्ति कोई पंक्तियाँ न लौटाए। यदि यह कोई चिंता का विषय नहीं है, तो आप इसे अन्यथा समकक्ष, कम क्रिया . का उपयोग कर सकते हैं एक निहित CROSS JOIN LATERAL
के साथ फॉर्म :
SELECT t.id, a.elem, a.nr
FROM tbl t, unnest(string_to_array(t.elements, ',')) WITH ORDINALITY a(elem, nr);
या वास्तविक सरणी पर आधारित होने पर आसान है (arr
एक सरणी स्तंभ होने के नाते):
SELECT t.id, a.elem, a.nr
FROM tbl t, unnest(t.arr) WITH ORDINALITY a(elem, nr);
या यहां तक कि, न्यूनतम सिंटैक्स के साथ:
SELECT id, a, ordinality
FROM tbl, unnest(arr) WITH ORDINALITY a;
a
स्वचालित रूप से तालिका और है स्तंभ उपनाम। जोड़े गए ऑर्डिनैलिटी कॉलम का डिफ़ॉल्ट नाम ordinality
है . लेकिन स्पष्ट कॉलम उपनाम और तालिका-योग्यता वाले कॉलम जोड़ना बेहतर (सुरक्षित, साफ-सुथरा) है।
8.4 - 9.3 पोस्ट करें
row_number() OVER (PARTITION BY id ORDER BY elem)
आपको क्रमांक क्रम के अनुसार नंबर मिलते हैं, न कि मूल क्रमिक स्थिति की क्रम संख्या के अनुसार स्ट्रिंग में।
आप बस ORDER BY
को छोड़ सकते हैं :
SELECT *, row_number() OVER (PARTITION by id) AS nr
FROM (SELECT id, regexp_split_to_table(elements, ',') AS elem FROM tbl) t;
हालांकि यह सामान्य रूप से काम करता है और मैंने इसे सरल प्रश्नों में कभी विफल नहीं देखा है, PostgreSQL ORDER BY
के बिना पंक्तियों के क्रम से संबंधित कुछ भी नहीं बताता है . यह एक कार्यान्वयन विवरण के कारण काम करता है।
क्रमिक संख्याओं की गारंटी . के लिए रिक्त-पृथक स्ट्रिंग . में तत्वों का :
SELECT id, arr[nr] AS elem, nr
FROM (
SELECT *, generate_subscripts(arr, 1) AS nr
FROM (SELECT id, string_to_array(elements, ' ') AS arr FROM tbl) t
) sub;
या वास्तविक सरणी पर आधारित होने पर आसान है :
SELECT id, arr[nr] AS elem, nr
FROM (SELECT *, generate_subscripts(arr, 1) AS nr FROM tbl) t;
dba.SE पर संबंधित उत्तर:
- एक नेस्टेड सरणी में तत्वों के मूल क्रम को कैसे सुरक्षित रखें?
पोस्टग्रेस 8.1 - 8.4
इनमें से कोई भी सुविधा अभी तक उपलब्ध नहीं है:RETURNS TABLE
, generate_subscripts()
, unnest()
, array_length()
. लेकिन यह काम करता है:
CREATE FUNCTION f_unnest_ord(anyarray, OUT val anyelement, OUT ordinality integer)
RETURNS SETOF record
LANGUAGE sql IMMUTABLE AS
'SELECT $1[i], i - array_lower($1,1) + 1
FROM generate_series(array_lower($1,1), array_upper($1,1)) i';
विशेष रूप से ध्यान दें, कि सरणी अनुक्रमणिका तत्वों की क्रमिक स्थिति से भिन्न हो सकती है। इस पर विचार करें विस्तारित फ़ंक्शन के साथ डेमो :
CREATE FUNCTION f_unnest_ord_idx(anyarray, OUT val anyelement, OUT ordinality int, OUT idx int)
RETURNS SETOF record
LANGUAGE sql IMMUTABLE AS
'SELECT $1[i], i - array_lower($1,1) + 1, i
FROM generate_series(array_lower($1,1), array_upper($1,1)) i';
SELECT id, arr, (rec).*
FROM (
SELECT *, f_unnest_ord_idx(arr) AS rec
FROM (VALUES (1, '{a,b,c}'::text[]) -- short for: '[1:3]={a,b,c}'
, (2, '[5:7]={a,b,c}')
, (3, '[-9:-7]={a,b,c}')
) t(id, arr)
) sub;
id | arr | val | ordinality | idx
----+-----------------+-----+------------+-----
1 | {a,b,c} | a | 1 | 1
1 | {a,b,c} | b | 2 | 2
1 | {a,b,c} | c | 3 | 3
2 | [5:7]={a,b,c} | a | 1 | 5
2 | [5:7]={a,b,c} | b | 2 | 6
2 | [5:7]={a,b,c} | c | 3 | 7
3 | [-9:-7]={a,b,c} | a | 1 | -9
3 | [-9:-7]={a,b,c} | b | 2 | -8
3 | [-9:-7]={a,b,c} | c | 3 | -7
तुलना करें:
- एक-आयामी सरणी के लिए सरणी सबस्क्रिप्ट को सामान्य करें ताकि वे 1 से शुरू हों