Negeys pozitsiyasi bilan REGEXP_SUBSTR

Vergulni satrda ajratuvchi sifatida tekshirish uchun so'rovlarim bor. So'nggi marta sodir bo'lishni xohlayman.

Masalan: string: a, b, c, d          string: e, f, g, h, i, j

select regexp_substr(string, '[^,]+', -1, 1)
from dual;

qaytib kelishi kerak: d va j

ammo xato xabari -1 pozitsiyasining oralig'i bo'lmaganligini bildiradi.

Oracle Doc: https://docs.oracle.com/cd/E11882_01/olap.112/e23381/row_functions063.htm#OLAXS456

1
Birinchi qatordagi bo'shliqlar bilan nima bo'ladi? Agar vergul haqiqiy chegarachi bo'lsa, u holda birinchi namunali satrdan olingan oxirgi "token" 'D' (ikki uzunlikdagi bir qator: bo'shliq va harf harfi).
qo'shib qo'ydi muallif mathguy, manba
Oracle ma'lumotlar bazasidan farq qiladigan alohida mahsulot bo'lgan Oracle OLAP-ga joylashtirilgan hujjatning murojaatlari. Agar sizda Oracle OLAP o'rnatilgan bo'lsa (nima demoqchi bo'lsam, menda hech qanday tasavvur yo'q) kengaytirilgan funksiyalarni regexp_substr va boshqa funktsiyalarga ega bo'lishi mumkin, ammo u Oracle ma'lumotlar bazasiga befarq bo'lmoqda. Standart Oracle SQL uchun regexp_substr hujjatlari salbiy joylashuvga ruxsat bermaydi.
qo'shib qo'ydi muallif mathguy, manba
Oracle ma'lumotlar bazasidan farq qiladigan alohida mahsulot bo'lgan Oracle OLAP-ga joylashtirilgan hujjatning murojaatlari. Agar sizda Oracle OLAP o'rnatilgan bo'lsa (nima demoqchi bo'lsam, menda hech qanday tasavvur yo'q) kengaytirilgan funksiyalarni regexp_substr va boshqa funktsiyalarga ega bo'lishi mumkin, ammo u Oracle ma'lumotlar bazasiga befarq bo'lmoqda. Standart Oracle SQL uchun regexp_substr hujjatlari salbiy joylashuvga ruxsat bermaydi.
qo'shib qo'ydi muallif mathguy, manba
Maydoni bilan mag'lubiyat qabul qila olaman.
qo'shib qo'ydi muallif dozel, manba
Maydoni bilan mag'lubiyat qabul qila olaman.
qo'shib qo'ydi muallif dozel, manba
Ma'qullangan. Rahmat
qo'shib qo'ydi muallif dozel, manba
Ma'qullangan. Rahmat
qo'shib qo'ydi muallif dozel, manba

7 javoblar

SELECT regexp_substr(string, '[^,]*$') FROM t

Sinov

3
qo'shib qo'ydi
@dozel Negativ pozitsiyani hech qachon ko'rmadim, hujjat noto'g'ri yoki kimdir mening bilganimdan ko'proq narsani biladi.
qo'shib qo'ydi muallif Mihai, manba
@Mihai - mening fikrimni original postda ko'rsating. Oracle OLAP Oracle ma'lumotlar bazasi bilan bir xil emas.
qo'shib qo'ydi muallif mathguy, manba
@dozel - Bu 11g hujjatidagi sahifadir - docs.oracle.com/cd/B28359_01/server.111/b28286/…
qo'shib qo'ydi muallif BriteSponge, manba
@dozel - Oracle docs bu musbat tamsayı bo'lishi kerakligini aytdi. 'Oracle ning qidirishni boshlashi kerak bo'lgan source_char xarakterini ko'rsatadigan ijobiy tamsayı. Sukut 1, ya'ni Oracle manba_charning birinchi belgisidan qidirishni boshlaydi. '
qo'shib qo'ydi muallif BriteSponge, manba
Ma'qullangan. Rahmat
qo'shib qo'ydi muallif dozel, manba
Bu ishlaydi, lekin oxirgi 2-chi voqeani olishni istasam nima bo'ladi. Muammo shundaki, Oracle hujjatlari, negativ int bilan ishora qilib, funktsiya orqaga qarab qidiradi. Nima uchun u ishlamayapti ekan? Oracle'dan olingan taklif: 'funktsiya izlashni boshlagan source_char xarakterini ko'rsatuvchi nol bo'lmagan tamsayı. Vaziyat salbiy bo'lganda, funktsiya mag'lubiyatning oxiridan orqada qoladi va izlaydi. Joylashuvning standart qiymati 1, ya'ni funktsiya manba_charning birinchi belgi bo'yicha qidirishni boshlaydi. '
qo'shib qo'ydi muallif dozel, manba
qo'shib qo'ydi muallif dozel, manba
SELECT regexp_substr(string, '[^,]*$') FROM t

Sinov

3
qo'shib qo'ydi
@dozel Negativ pozitsiyani hech qachon ko'rmadim, hujjat noto'g'ri yoki kimdir mening bilganimdan ko'proq narsani biladi.
qo'shib qo'ydi muallif Mihai, manba
@Mihai - mening fikrimni original postda ko'rsating. Oracle OLAP Oracle ma'lumotlar bazasi bilan bir xil emas.
qo'shib qo'ydi muallif mathguy, manba
@dozel - Oracle docs bu musbat tamsayı bo'lishi kerakligini aytdi. 'Oracle ning qidirishni boshlashi kerak bo'lgan source_char xarakterini ko'rsatadigan ijobiy tamsayı. Sukut 1, ya'ni Oracle manba_charning birinchi belgisidan qidirishni boshlaydi. '
qo'shib qo'ydi muallif BriteSponge, manba
@dozel - Bu 11g hujjatidagi sahifadir - docs.oracle.com/cd/B28359_01/server.111/b28286/…
qo'shib qo'ydi muallif BriteSponge, manba
Ma'qullangan. Rahmat
qo'shib qo'ydi muallif dozel, manba
Bu ishlaydi, lekin oxirgi 2-chi voqeani olishni istasam nima bo'ladi. Muammo shundaki, Oracle hujjatlari, negativ int bilan ishora qilib, funktsiya orqaga qarab qidiradi. Nima uchun u ishlamayapti ekan? Oracle'dan olingan taklif: 'funktsiya izlashni boshlagan source_char xarakterini ko'rsatuvchi nol bo'lmagan tamsayı. Vaziyat salbiy bo'lganda, funktsiya mag'lubiyatning oxiridan orqada qoladi va izlaydi. Joylashuvning standart qiymati 1, ya'ni funktsiya manba_charning birinchi belgi bo'yicha qidirishni boshlaydi. '
qo'shib qo'ydi muallif dozel, manba
qo'shib qo'ydi muallif dozel, manba

Mana buni amalga oshirishingiz mumkin bo'lgan bir nechta usul:

WITH sample_data AS (SELECT 'a, b, c, d' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i, j' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i, jk' str FROM dual UNION ALL
                     SELECT 'e,f,g,h,i,jk' str FROM dual UNION ALL
                     SELECT 'e,f,g,h,i,' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i,' str FROM dual)
SELECT str,
       ltrim(SUBSTR(str, INSTR(str, ',', -1, 1) + 1)) last_item1,
       regexp_substr(str, '.*, ?([^,]*$)', 1, 1, NULL, 1) last_item3
FROM   sample_data;

STR               LAST_ITEM1        LAST_ITEM3
----------------- ----------------- -----------------
a, b, c, d        d                 d
e, f, g, h, i, j  j                 j
e, f, g, h, i, jk jk                jk
e,f,g,h,i,jk      jk                jk
e,f,g,h,i,                          
e, f, g, h, i,                      

Bu sizning tizimingizda eng yaxshi va/yoki saqlab turiladigan ikkita variantning biridan ikkinchisidir. Buni sinash kerak.

Yuqoridagi regexp_substr echimi har qanday belgidan (yangi qatordan tashqari), keyinroq vergul bilan, keyin bo'sh joy (yoki emas) va keyin oxirida simni oxiriga qadar vergul bo'lmagan har qanday belgini tekshiradi. Keyin biz birinchi subexpressionni chiqardik (bu naqshning parchalanish qismi bilan belgilanadi).

Mintaqadagi plitkani ichiga kiritdim, chunki siz chegarachingiz vergul ekanligini aytdingiz, lekin u xuddi vergul + bo'sh joy edi.

2
qo'shib qo'ydi
@Boneist - OP'dan so'radim va u vergulni haqiqiy chegaralovchi deb javob berdi; agar mavjud bo'lsa, bo'sh joylar saqlanishi kerak. (Yoki ular saqlanib qolsa, "OK"). Agar shunday bo'lsa, standart tasma funktsiyalaridan foydalangan holda, muntazam ifodalarni ishlatadigan echimlar yanada samaraliroq bo'ladi.
qo'shib qo'ydi muallif mathguy, manba
@dozel - Oracle OLAP (alohida mahsulot) standart Oracle SQL (Oracle ma'lumotlar bazasi) bilan aralashtirmang!
qo'shib qo'ydi muallif mathguy, manba
Buning sababi, siz ko'rib chiqqan hujjatlar (eski formatda bo'lgan va shuning uchun eskirib qolgan bo'lishi ehtimoldan holi emas), unda xato yuzaga keladi. Siz REGEXP_SUBSTR da pozitsiyada yoki holatda salbiy sonlarga ega bo'lolmaysiz.
qo'shib qo'ydi muallif Boneist, manba
yangi doc ham xuddi shunday deydi :( docs.oracle. MAQOMOTI/CD/E11882_01/olap.112/e23381/& hellip; ). Lekin, ehtimol siz haqsiz, doktorning kamchiliklari bor.
qo'shib qo'ydi muallif dozel, manba
Savolimga ko'ra, -1-raqamni ishlatish nima uchun ishlamayapti, shuning uchun Oracle doc, biz orqaga qarab qidirmoqchi bo'lsak, biz negiz int ni ishlatishimiz mumkinligini aytadi. Men substr va instr bilan o'ynashim mumkin, lekin nima uchun men juda oddiy usulda bo'lishim kerak.
qo'shib qo'ydi muallif dozel, manba

Mana buni amalga oshirishingiz mumkin bo'lgan bir nechta usul:

WITH sample_data AS (SELECT 'a, b, c, d' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i, j' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i, jk' str FROM dual UNION ALL
                     SELECT 'e,f,g,h,i,jk' str FROM dual UNION ALL
                     SELECT 'e,f,g,h,i,' str FROM dual UNION ALL
                     SELECT 'e, f, g, h, i,' str FROM dual)
SELECT str,
       ltrim(SUBSTR(str, INSTR(str, ',', -1, 1) + 1)) last_item1,
       regexp_substr(str, '.*, ?([^,]*$)', 1, 1, NULL, 1) last_item3
FROM   sample_data;

STR               LAST_ITEM1        LAST_ITEM3
----------------- ----------------- -----------------
a, b, c, d        d                 d
e, f, g, h, i, j  j                 j
e, f, g, h, i, jk jk                jk
e,f,g,h,i,jk      jk                jk
e,f,g,h,i,                          
e, f, g, h, i,                      

Bu sizning tizimingizda eng yaxshi va/yoki saqlab turiladigan ikkita variantning biridan ikkinchisidir. Buni sinash kerak.

Yuqoridagi regexp_substr echimi har qanday belgidan (yangi qatordan tashqari), keyinroq vergul bilan, keyin bo'sh joy (yoki emas) va keyin oxirida simni oxiriga qadar vergul bo'lmagan har qanday belgini tekshiradi. Keyin biz birinchi subexpressionni chiqardik (bu naqshning parchalanish qismi bilan belgilanadi).

Mintaqadagi plitkani ichiga kiritdim, chunki siz chegarachingiz vergul ekanligini aytdingiz, lekin u xuddi vergul + bo'sh joy edi.

2
qo'shib qo'ydi
@Boneist - OP'dan so'radim va u vergulni haqiqiy chegaralovchi deb javob berdi; agar mavjud bo'lsa, bo'sh joylar saqlanishi kerak. (Yoki ular saqlanib qolsa, "OK"). Agar shunday bo'lsa, standart tasma funktsiyalaridan foydalangan holda, muntazam ifodalarni ishlatadigan echimlar yanada samaraliroq bo'ladi.
qo'shib qo'ydi muallif mathguy, manba
@dozel - Oracle OLAP (alohida mahsulot) standart Oracle SQL (Oracle ma'lumotlar bazasi) bilan aralashtirmang!
qo'shib qo'ydi muallif mathguy, manba
Buning sababi, siz ko'rib chiqqan hujjatlar (eski formatda bo'lgan va shuning uchun eskirib qolgan bo'lishi ehtimoldan holi emas), unda xato yuzaga keladi. Siz REGEXP_SUBSTR da pozitsiyada yoki holatda salbiy sonlarga ega bo'lolmaysiz.
qo'shib qo'ydi muallif Boneist, manba
yangi doc ham xuddi shunday deydi :( docs.oracle. MAQOMOTI/CD/E11882_01/olap.112/e23381/& hellip; ). Lekin, ehtimol siz haqsiz, doktorning kamchiliklari bor.
qo'shib qo'ydi muallif dozel, manba
Savolimga ko'ra, -1-raqamni ishlatish nima uchun ishlamayapti, shuning uchun Oracle doc, biz orqaga qarab qidirmoqchi bo'lsak, biz negiz int ni ishlatishimiz mumkinligini aytadi. Men substr va instr bilan o'ynashim mumkin, lekin nima uchun men juda oddiy usulda bo'lishim kerak.
qo'shib qo'ydi muallif dozel, manba

Regexp bo'lmagan yechim bo'lishi mumkin:

select substr(string, instr( string, ',', -1)+1)
from yourTable

Bu erda instr dan foydalaning, agar mavjud bo'lsa, so'ngra faqatgina substr ni toping.

2
qo'shib qo'ydi

Regexp bo'lmagan yechim bo'lishi mumkin:

select substr(string, instr( string, ',', -1)+1)
from yourTable

Bu erda instr dan foydalaning, agar mavjud bo'lsa, so'ngra faqatgina substr ni toping.

2
qo'shib qo'ydi

Agar siz 2-chi voqeani olishni istasangiz, nima deyilgan? 4-argument qaytib kelmoqchi bo'lgan element. Ushbu format NULL elementlarini boshqaradi:

with tbl(str) as (
  select 'a, b, c, d' from dual union
  select 'e,,g,h,i,j' from dual
)
select regexp_substr(str, '(.*?)(,|$)', 1, 2, NULL, 1) element
from tbl; 
1
qo'shib qo'ydi