आदर्श तरीका यह होगा कि सामान्यीकृत करें अपना डेटा और कॉलम के दो घटकों को दो अलग-अलग कॉलम में विभाजित करें। एक प्रकार का integer
, एक text
।
वर्तमान तालिका के साथ, आप यहां प्रदर्शित कुछ ऐसा कर सकते हैं:
WITH x(t) AS (
VALUES
('10_asdaasda')
,('100_inkskabsjd')
,('11_kancaascjas')
,('45_aksndsialcn')
,('22_dsdaskjca')
,('100_skdnascbka')
)
SELECT t
FROM x
ORDER BY (substring(t, '^[0-9]+'))::int -- cast to integer
,substring(t, '[^0-9_].*$') -- works as text
वही substring()
एक्सप्रेशन का उपयोग कॉलम को विभाजित करने के लिए किया जा सकता है।
रेगुलर एक्सप्रेशन कुछ हद तक दोष सहिष्णु हैं:
-
पहला रेगेक्स बाईं ओर से सबसे लंबी संख्यात्मक स्ट्रिंग चुनता है,
NULL
यदि कोई अंक नहीं मिलते हैं, तोinteger
. पर कास्ट करें गलत नहीं हो सकता। -
दूसरा रेगेक्स शेष स्ट्रिंग को पहले वर्ण से चुनता है जो अंक या '_' नहीं है।
यदि अंडरस्कोर वैसे भी विभाजक के रूप में स्पष्ट है, split_part()
तेज़ है:
ORDER BY (split_part(t, '_', 1)::int
,split_part(t, '_', 2)
अपने उदाहरण के लिए उत्तर दें
SELECT name
FROM nametable
ORDER BY (split_part(name, '_', 1)::int
,split_part(name, '_', 2)