एक अनावश्यक सरणी में तत्वों के मूल क्रम को कैसे संरक्षित करें?


19

स्ट्रिंग को देखते हुए:

'मुझे लगता है कि PostgreSQL निफ्टी है'

मैं उस स्ट्रिंग के भीतर पाए गए व्यक्तिगत शब्दों पर काम करना चाहूंगा। अनिवार्य रूप से, मेरे पास एक अलग है जिससे मैं शब्द विवरण प्राप्त कर सकता हूं और इस शब्दकोश में उस स्ट्रिंग के एक अनावश्यक सरणी में शामिल होना चाहूंगा।

अब तक मेरे पास:

select word, meaning, partofspeech
from unnest(string_to_array('I think that PostgreSQL is nifty',' ')) as word
from table t
join dictionary d
on t.word = d.wordname;

यह उन मूल सिद्धांतों को पूरा करता है जो मैं करने की उम्मीद कर रहा था, लेकिन यह मूल शब्द क्रम को संरक्षित नहीं करता है।

संबंधित प्रश्न:
तत्व संख्या के साथ पोस्टग्रेक्सेल अनावश्यक ()


क्या आप एक स्ट्रिंग या स्ट्रिंग की एक पूरी तालिका को संसाधित करना चाहते हैं ? यदि हां, तो क्या टेबल में एक प्राथमिक कुंजी है?
एरविन ब्रांडस्टेट्टर

@ErwinBrandstetter एक तालिका में एक स्ट्रिंग (जिसमें एक प्राथमिक कुंजी है)
swasheck को

जवाबों:


24

WITH ORDINALITY Postgres में 9.4 या बाद में

नई सुविधा समस्याओं के इस वर्ग को सरल बनाती है। उपरोक्त क्वेरी अब बस हो सकती है:

SELECT *
FROM   regexp_split_to_table('I think Postgres is nifty', ' ') WITH ORDINALITY x(word, rn);

या, एक मेज पर लागू:

SELECT *
FROM   tbl t, regexp_split_to_table(t.my_column, ' ') WITH ORDINALITY x(word, rn);

विवरण:

निहित जुड़ाव के बारे में LATERAL:

9.3 या पुराने पोस्टग्रेट्स - और अधिक सामान्य स्पष्टीकरण

एक तार के लिए

आप row_number()तत्वों के क्रम को याद रखने के लिए विंडो फ़ंक्शन को लागू कर सकते हैं। हालांकि, सामान्य क्रमrow_number() OVER (ORDER BY col) में आपको क्रमबद्ध क्रम के अनुसार नंबर मिलते हैं , न कि स्ट्रिंग में मूल स्थिति

आप बस ORDER BY"जैसा है" स्थिति प्राप्त करने के लिए छोड़ सकते हैं :

SELECT *, row_number() OVER () AS rn
FROM   regexp_split_to_table('I think Postgres is nifty', ' ') AS x(word);

regexp_split_to_table()लंबे स्ट्रिंग्स के साथ गिरावट का प्रदर्शन । unnest(string_to_array(...))तराजू बेहतर:

SELECT *, row_number() OVER () AS rn
FROM   unnest(string_to_array('I think Postgres is nifty', ' ')) AS x(word);

हालाँकि, जबकि यह सामान्य रूप से काम करता है और मैंने इसे सरल प्रश्नों में कभी टूटते नहीं देखा, पंक्तियों को स्पष्ट किए बिना पंक्तियों के क्रम के रूप में कुछ भी नहीं बताता है ORDER BY

मूल स्ट्रिंग में तत्वों की क्रमिक संख्या की गारंटी देने के लिए , उपयोग करें generate_subscript()(@deszo द्वारा टिप्पणी के साथ सुधार):

SELECT arr[rn] AS word, rn
FROM   (
   SELECT *, generate_subscripts(arr, 1) AS rn
   FROM   string_to_array('I think Postgres is nifty', ' ') AS x(arr)
   ) y;

तार की एक तालिका के लिए

जोड़े PARTITION BY idको OVERखंड ...

डेमो तालिका:

CREATE TEMP TABLE strings(string text);
INSERT INTO strings VALUES
  ('I think Postgres is nifty')
 ,('And it keeps getting better');

मैं ctidएक प्राथमिक कुंजी के लिए तदर्थ विकल्प के रूप में उपयोग करता हूं । यदि आपके पास एक (या कोई अनूठा स्तंभ ) है, तो इसके बजाय उसका उपयोग करें।

SELECT *, row_number() OVER (PARTITION BY ctid) AS rn
FROM  (
   SELECT ctid, unnest(string_to_array(string, ' ')) AS word
   FROM   strings
   ) x;

यह बिना किसी अलग पहचान के काम करता है:

SELECT arr[rn] AS word, rn
FROM  (
   SELECT *, generate_subscripts(arr, 1) AS rn
   FROM  (
      SELECT string_to_array(string, ' ') AS arr
      FROM   strings
      ) x
   ) y;

एसक्यूएल फिडल।

सवाल का जवाब

SELECT z.arr, z.rn, z.word, d.meaning   -- , partofspeech -- ?
FROM  (
   SELECT *, arr[rn] AS word
   FROM  (
      SELECT *, generate_subscripts(arr, 1) AS rn
      FROM  (
         SELECT string_to_array(string, ' ') AS arr
         FROM   strings
         ) x
      ) y
   ) z
JOIN   dictionary d ON d.wordname = z.word
ORDER  BY z.arr, z.rn;

1
आप Pg की विचित्र SRF-in-SELECT-list व्यवहार का भी शोषण कर सकते हैं SELECT generate_series(1,array_length(word_array,1)), unnest(word_array) FROM ....:। 9.3 LATERALइस समस्या के लिए अच्छे समाधान प्रदान कर सकता है।
क्रेग रिंगर

2
के generate_subscripts(arr, 1)बजाय काम नहीं करेगा generate_series(1, array_upper(arr, 1))? मैं स्पष्टता के लिए पूर्व पसंद करेंगे।
dezso

1
@Erwin क्या आपने डेसेंज़ से ORDINALITY पोस्ट देखी है ?
जैक डगलस

1
@JackDouglas: जैसा कि होता है, हमारे बीच शुक्रवार को संबंधित विषय पर चर्चा हुई , जो मुझे एक समान खोज की ओर ले गई। मैंने जवाब में थोड़ा जोड़ा।
एरविन ब्रान्डसेट्टर

1
"विवरण" के लिए लिंक बस इसी पृष्ठ पर लिंक करता है। वह भ्रामक है।
वाइल्डकार्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.