sql - Split_part का उपयोग करने के बाद रिक्त फ़ील्ड में मान को प्रतिस्थापित करना




postgresql natural-sort (4)

मेरे पास दो स्तंभ हैं, id integer और version text मैं version में स्ट्रिंग को पूर्णांक में कनवर्ट करने की कोशिश कर रहा हूं ताकि मैं आईडी का अधिकतम (सबसे हाल का) संस्करण चुन सकूं।

हालांकि, id का पहला उदाहरण स्वयं को version रूप में संग्रहीत करता है उदाहरण:

id | version
---+--------
10 | '10'

विरोध के रूप में:

id | version
---+--------
10 | '10-0'

अतिरिक्त पंक्तिएं कन्वेंशन आईडी का अनुसरण करती हैं: 10, संस्करण: 10-1 आदि।

मैं यह कैसे हासिल कर सकता हूं? मैंने split_part() की कोशिश की है और int रूप में डाली। हालांकि, split_part(version, "-", 2) वापस एक रिक्त स्ट्रिंग की तरह दिखाई देगा। मैंने इसे COALESCE(splitpart..., '0') करने के लिए कोई लाभ नहीं उठाया है क्योंकि यह फील्ड इंडेक्स 2 द्वारा रिक्त फ़ील्ड को पढ़ने की कोशिश करता है।


Answers

संगठित () और नलिफ़ () के संयोजन का उपयोग करें , उदाहरण:

with my_table(version) as (
values
    ('10'), ('10-1'), ('10-2')
)

select 
    version, 
    split_part(version, '-', 1)::int as major, 
    coalesce(nullif(split_part(version, '-', 2), ''), '0')::int as minor
from my_table

 version | major | minor 
---------+-------+-------
 10      |    10 |     0
 10-1    |    10 |     1
 10-2    |    10 |     2
(3 rows)    

split_part() रिक्त स्ट्रिंग देता है ( '' ) - NULL नहीं - जब वापस लौटाया भाग खाली या गैर-मौजूद है यही कारण है कि COALESCE यहाँ कुछ नहीं करता है और खाली स्ट्रिंग ( '' ) का integer मान के रूप में कोई प्रतिनिधित्व नहीं है, इसलिए इसे डालने का प्रयास करते समय एक त्रुटि फेंकता है।

कास्टिंग से पहले इस उदाहरण में सबसे छोटा रास्ता GREATEST(split_part( ... ) , '0') होना चाहिए, क्योंकि रिक्त स्ट्रिंग किसी भी अन्य गैर-रिक्त स्ट्रिंग से पहले या किसी GREATEST(split_part( ... ) , '0') किसी भी स्थान में) से पहले भी होनी चाहिए। फिर प्रत्येक id लिए "सबसे बड़ा" version साथ पंक्ति प्राप्त करने के लिए DISTINCT ON () का उपयोग करें

परीक्षण व्यवस्था

CREATE TABLE tbl (
   id      integer NOT NULL
 , version text    NOT NULL
);

INSERT INTO tbl VALUES
     (10, '10-2')
   , (10, '10-1')
   , (10, '10')      -- missing subversion
   , (10, '10-111')  -- multi-digit number
   , (11, '11-1')
   , (11, '11-0')    -- proper '0'
   , (11, '11-')     -- missing subversion but trailing '-'
   , (11, '11-2');

समाधान की

SELECT DISTINCT ON (id) *
FROM   tbl
ORDER  BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;

परिणाम:

 id | version 
----+---------
 10 | 10-111
 11 | 10-2

या आप NULLIF का उपयोग भी कर सकते हैं और सॉर्ट करने के लिए NULLS LAST (अवरोही क्रम में) का उपयोग कर सकते हैं:

SELECT DISTINCT ON (id) *
FROM   tbl
ORDER  BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;

उसी परिणाम

या एक और स्पष्ट CASE बयान:

CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END

dbfiddle यहाँ

सम्बंधित:


संस्करण स्ट्रिंग्स के आसपास पाने के लिए, जिसमें कोई हाइफ़न नहीं है, आप एक CASE अभिव्यक्ति का उपयोग कर सकते हैं:

CASE WHEN version LIKE '%-%'
     THEN SPLIT_PART(version, '-', 2)::int
     ELSE 0 END

मूल विचार संस्करण संख्या का उपयोग करना है, एक इंट्रान को डाला जाता है, जब एक हाइफ़न मौजूद होता है, लेकिन अन्यथा यह मानने के लिए कि शून्य शून्य है यदि संस्करण शून्य है।

रास्ते में से इस बाधा को बाहर करने के साथ, आपकी क्वेरी अब केवल एक ROW_NUMBER() क्वेरी में कम कर देता है यहां, विभाजन id , और संस्करण के लिए उपरोक्त CASE अभिव्यक्ति का उपयोग करके आदेश दिया गया है।

SELECT
    t.id, t.version
FROM
(
    SELECT
        id,
        CASE WHEN version LIKE '%-%'
             THEN version
             ELSE version || '-0' END AS version,
        ROW_NUMBER() OVER (PARTITION BY id
                           ORDER BY
                               CASE WHEN version LIKE '%-%'
                                    THEN SPLIT_PART(version, '-', 2)::int
                                    ELSE 0 END DESC) rn
    FROM yourTable
) t
WHERE t.rn = 1
ORDER BY t.id;

डेमो यहां:

Rextester


MySQL (5.6.13) सत्र चर और असाइनमेंट ऑपरेटर का उपयोग निम्न की तरह करें

SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a;

तो आप प्राप्त कर सकते हैं

test1,test11




sql postgresql split natural-sort