2012-04-11 25 views
5

पोस्टग्रेज़ में फ़ंक्शन कैसे करें जो स्ट्रिंग या सरणी लेता है और कुछ लंबाई के सभी संयोजनों को वापस लाता है?दोहराए बिना पोस्टग्रेएसक्यूएल संयोजन

उदाहरण के लिए आप एबीसी है और आप 2 पात्रों के साथ संयोजन प्राप्त करना चाहते हैं, नतीजा हो shoul:

एबी एसी ई.पू.

आपकी मदद के लिए अग्रिम धन्यवाद।

+0

क्यों आप एक डीबीएमएस में है कि क्या करना होगा से प्रेरित? क्या आप इसे एप्लिकेशन स्तर पर नहीं कर सकते? –

+0

मैं सुडोकू-सॉल्वर में उपयोग का उपयोग कर सकता हूं ;-) – wildplasser

+0

मैं इसे एकाधिक प्रोग्रामिंग भाषाओं में और केवल एक डेटाबेस PostgreSQL में उपयोग करूंगा, इसलिए मैं सोच रहा था कि यह एक ही स्थान पर यह सबसे आसान तरीका होगा। इसे स्ट्रिंग में शामिल होने की आवश्यकता नहीं है, मैं केवल परेशानी देता हूं कि काम कैसे करना चाहिए। – ffox003

उत्तर

9
set search_path='tmp'; 

WITH ztab AS (
SELECT idx as idx 
, substring ('WTF!' FROM idx FOR 1) as str 
FROM generate_series(1, char_length('WTF!')) idx 
) 
SELECT t1.str, t2.str 
FROM ztab t1 
JOIN ztab t2 ON t2.idx > t1.idx 
     ; 

परिणाम:

str | str 
-----+----- 
W | T 
W | F 
W | ! 
T | F 
T | ! 
F | ! 
(6 rows) 

दुर्भाग्य से मैं एक तरह से डबल स्ट्रिंग निरंतर से बचने के लिए नहीं मिल रहा। (लेकिन पूरी चीज को फ़ंक्शन में पैक किया जा सकता है) यदि कोई डुप्लिकेट वर्ण नहीं हैं (या आप उन्हें suppres करना चाहते हैं) तो आप idx के बजाय str पर एंटी-जॉइन कर सकते हैं।

अद्यतन (ypercube से संकेत) ऐसा लगता है कि ओपी चाहता है कि तारों को संयोजित किया जाए। तो यह हो सकता है ::

WITH ztab AS (
SELECT idx as idx 
, substring ('WTF!' FROM idx FOR 1) as str 
FROM generate_series(1, char_length('WTF!')) idx 
) 
SELECT t1.str || t2.str AS results 
FROM ztab t1 
JOIN ztab t2 ON t2.idx > t1.idx 
     ; 

परिणाम: (... यहाँ पुनरावर्ती thingy आता है)

WITH RECURSIVE xtab AS (
     WITH no_cte AS (
     SELECT 
     1::int AS len 
     , idx as idx 
     , substring ('WTF!' FROM idx FOR 1) as str 
     FROM generate_series(1, char_length('WTF!')) idx 
     ) 
     SELECT t0.len as len 
       , t0.idx 
       , t0.str 
     FROM no_cte t0 
     UNION SELECT 1+t1.len 
       , tc.idx 
       , t1.str || tc.str AS str 
     FROM xtab t1 
     JOIN no_cte tc ON tc.idx > t1.idx 
     ) 
SELECT * FROM xtab 
ORDER BY len, str 
-- WHERE len=2 
     ; 

परिणाम 3:

results 
--------- 
WT 
WF 
W! 
TF 
T! 
F! 
(6 rows) 

UPDATE2

len | idx | str 
-----+-----+------ 
    1 | 4 | ! 
    1 | 3 | F 
    1 | 2 | T 
    1 | 1 | W 
    2 | 4 | F! 
    2 | 4 | T! 
    2 | 3 | TF 
    2 | 4 | W! 
    2 | 3 | WF 
    2 | 2 | WT 
    3 | 4 | TF! 
    3 | 4 | WF! 
    3 | 4 | WT! 
    3 | 3 | WTF 
    4 | 4 | WTF! 
(15 rows) 
+0

अच्छा समाधान! –

+0

टीएनएक्स! मुझे नहीं लगता कि gener_series() फ़ंक्शन टेक्स्ट तर्क स्वीकार करता है (मैंने इसे भी नहीं देखा), इसलिए यह बदसूरत हैक वास्तव में उसके आस-पास एक तरीका है। – wildplasser

+0

क्या बदसूरत हैक? (ओह, और चयन 'SELECT t1.str || t2.str AS परिणाम' या 'SELECT t1.str AS str1, t2.str AS str2') –

1
with chars as (
    select unnest(regexp_split_to_array('ABC','')) as c 
) 
select c1.c||c2.c 
from chars c1 
    cross join chars c2 

क्रमपरिवर्तन को निकालने के लिए आप निम्न का उपयोग कर सकते हैं:

with chars as (
    select unnest(regexp_split_to_array('ABC','')) as c 
) 
select c1.c||c2.c 
from chars c1 
    cross join chars c2 
where c1.c < c2.c 
+0

यह मेरे मुकाबले बहुत अधिक सुरुचिपूर्ण दिखता है ;-(जैसा कि मैंने कहा: मुझे स्ट्रिंग पसंद नहीं है। बीटीडब्ल्यू यह क्रमपरिवर्तन को दबाता है? – wildplasser

+0

@ विल्डप्लेसर: क्या आपका मतलब एबी और बीए के समान है?मैंने अपना जवाब –

+0

संपादित किया जो मेरा मतलब था। एक समान समस्या स्ट्रिंग में डुप्लिकेट वर्ण होंगे, जैसे कि "एबीबीए"। (इसे ओपी में संबोधित नहीं किया गया था) – wildplasser

0

अनेक शब्दों से कैसे काम करता है के लिए ... @wildplasser से और इस स्रोत info

WITH RECURSIVE xtab AS (
    WITH no_cte AS (
    SELECT 
    1::int AS len 
    , idx as idx 
    , unnest(ARRAY['MY','POSTGRESQL','VERSION','9.6']) as str 
    FROM generate_series(1, array_length(ARRAY['MY','POSTGRESQL','VERSION','9.6'],1)) idx 
    ) 
    SELECT t0.len as len 
      , t0.idx 
      , t0.str 
    FROM no_cte t0 
    UNION SELECT 1+t1.len 
      , tc.idx 
      , t1.str ||','|| tc.str AS str 
    FROM xtab t1 
    JOIN no_cte tc ON tc.idx > t1.idx 
    ) 
    SELECT distinct 
    array_to_string(ARRAY(SELECT DISTINCT trim(x) FROM unnest(string_to_array(str,',')) x),', ') FROM xtab 
संबंधित मुद्दे