Display city names which start and end with vowels [duplicate] - sql

This question already has answers here:
Oracle REGEXP confusion
(2 answers)
Closed 7 months ago.
I have been trying to write a SQL query to get city names start and end with vowels only.
Code:
select distinct city
from station
where REGEXP_LIKE (city, '^(a|e|i|o|u).*(a|e|i|o|u)$');
This above query gives me the wrong answer. I am using Oracle.

Here is a more concise way to write your query using REGEXP_LIKE:
SELECT DISTINCT city
FROM station
WHERE REGEXP_LIKE(city, '^[aeiou].*[aeiou]$', 'i');
The third match parameter i tells Oracle to do a case insensitive search. This frees us from the need of listing out uppercase and lowercase vowels.

You can use regular expressions, but - you can also use substr function. For example:
SQL> with city (name) as
2 (select 'BOSTON' from dual union all
3 select 'ALBUQUERQUE' from dual
4 )
5 select name,
6 case when substr(upper(name), 1, 1) in ('A', 'E', 'I', 'O', 'U') and
7 substr((name), -1) in ('A', 'E', 'I', 'O', 'U')
8 then 'OK'
9 else 'Not OK'
10 end as result_1,
11 --
12 case when regexp_like(name, '^[aeiou].*[aeiou]$', 'i') then 'OK'
13 else 'Not OK'
14 end as result_2
15 from city;
NAME RESULT_1 RESULT_2
----------- ---------- ----------
BOSTON Not OK Not OK
ALBUQUERQUE OK OK
SQL>

I am able to write answer for it
Query :
select distinct city from station where regex_like ( city,'^(a|e|i|o|u|A|E|I|O|U).*(a|e|i|o|u|A|E|I|O|U)$');

Related

SQL remove unwanted special characters from a string

Hi i am new to SQL and am writing a case statement for a column of grade values.
The values can be a length of 3 like A02, B04, A10, A09, D03. The first character is a letter while the next 2 are digits.
If a user enters in 'A02 I want to change it to do A02. Basically remove any special characters if there are present.
CASE
WHEN Grade like '[^0-9A-z]%' THEN ''
else Grade end as Grade
So far I have this but I am not sure how to use regex to remove the character only search for it.
Unless you really want to do a CASE for the fun of it, in oracle I'd do it like this which removes punctuation characters and spaces when you select it. Note this does not verify format so a grade of Z1234 would get returned.
WITH tbl(ID, grade) AS (
SELECT 1, 'A01' FROM dual UNION ALL
SELECT 1, '''B02' FROM dual UNION ALL
SELECT 2, '$ C01&' FROM dual
)
SELECT ID, grade, REGEXP_REPLACE(grade, '([[:punct:]]| )') AS grade_scrubbed
from tbl;
ID GRADE GRADE_SCRUBBED
---------- --------- --------------
1 A01 A01
1 'B02 B02
2 $ C01& C01
3 rows selected.
HOWEVER, that said, since you seem to want to verify the format and use regex, you could do it this way although it's a little fugly. See comments.
WITH tbl(ID, grade) AS (
-- Test data. Include every crazy combo you'd never expect to see,
-- because you WILL see it, it's just a matter of time :-)
SELECT 1, 'A01' FROM dual UNION ALL
SELECT 1, '''B02' FROM dual UNION ALL
SELECT 2, '$ C01&' FROM dual UNION ALL
SELECT 3, 'DDD' FROM dual UNION ALL
SELECT 4, 'A'||CHR(10)||'DEF' FROM dual UNION ALL
SELECT 5, 'Z1234' FROM dual UNION ALL
SELECT 6, NULL FROM dual
)
SELECT ID, grade,
CASE
-- Correct format of A99.
WHEN REGEXP_LIKE(grade, '^[A-Z]\d{2}$')
THEN grade
-- if not A99, see if stripping out punctuation and spaces make it match A99.
-- If so, return with punctuation and spaces stripped out.
WHEN NOT REGEXP_LIKE(grade, '^[A-Z]\d{2}$')
AND REGEXP_LIKE(REGEXP_REPLACE(grade, '([[:punct:]]| )'), '^[A-Z]\d{2}$')
THEN REGEXP_REPLACE(grade, '([[:punct:]]| )')
-- if not A99, and stripping out punctuation and spaces didn't make it match A99,
-- then the grade is in the wrong format.
WHEN NOT REGEXP_LIKE(grade, '^[A-Z]\d{2}$')
AND NOT REGEXP_LIKE(REGEXP_REPLACE(grade, '([[:punct:]]| )'), '^[A-Z]\d{2}$')
THEN 'Invalid grade format'
-- Something fell through all cases we tested for. Always expect the unexpected!
ELSE 'No case matched!'
END AS grade_scrubbed
from tbl;
ID GRADE GRADE_SCRUBBED
---------- -------------------- --------------------
1 A01 A01
1 'B02 B02
2 $ C01& C01
3 DDD Invalid grade format
4 A
DEF Invalid grade format
5 Z1234 Invalid grade format
6 No case matched!
7 rows selected.

Concat subquery with other columns

I have a query that returns many columns concated with : ,
SELECT DECODE(ship_ps.STATUS, 'A', 'Y', 'N') AS isactive_ship
,ship_ps.party_site_id
,ship_ps.party_site_number AS site_number
,ship_ps.col1 || ship_ps.col 2
from ...
where ....
and i have a seprate query
(SELECT hp.party_name
FROM apps.hz_cust_accounts hca,apps.hz_parties hp
WHERE 1=1
AND hp.party_id=hca.party_id
AND hca.status='A'
AND hca.cust_account_id=:p_sold_to_org_id6)
i want to concat the result of it with ship_ps.col1 || ship_ps.col 2 || THE_QUERY
How to achieve that
Did you try to run the SQL and got an error?:
SQL> select dummy||' '||(select 1 from dual) from dual;
DUMMY||''||(SELECT1FROMDUAL)
------------------------------------------
X 1

Extracting substring in Oracle

Let's say I have three rows with value as
1 121/2808B|:6081
2 OD308B|:6081_1:
3 008312100001200|:6081_1
I want to display value only until B but want to exclude everything after B. So as you can see in above data:
from 121/2808B|:6081 I want only 121/2808B
from OD308B|:6081_1: only OD308B
from 008312100001200|:6081_1 only 008312100001200.
Thanks for the Help.
Try this: regexp_substr('<Your_string>','[^B]+')
SELECT
REGEXP_SUBSTR('121/2808B|:6081', '[^B]+')
FROM
DUAL;
REGEXP_S
--------
121/2808
SELECT
REGEXP_SUBSTR('OD308B|:6081_1:', '[^B]+')
FROM
DUAL;
REGEX
-----
OD308
SELECT
REGEXP_SUBSTR('008312100001200.', '[^B]+')
FROM
DUAL;
REGEXP_SUBSTR('0
----------------
008312100001200.
db<>fiddle demo
Cheers!!
You could try using SUBSTR() and INSTR()
select SUBSTR('121/2808B|:6081',1,INSTR('121/2808B|:6081','B', 1, 1) -1)
from DUAL
I think you forgot to mention that you wanted to use | as a field separator, but I deduced this from the expected result from the third string. As such the following should give you what you want:
WITH cteData AS (SELECT 1 AS ID, '121/2808B|:6081' AS STRING FROM DUAL UNION ALL
SELECT 2, 'OD308B|:6081_1:' FROM DUAL UNION ALL
SELECT 3, '008312100001200|:6081_1' FROM DUAL)
SELECT ID, STRING, SUBSTR(STRING, 1, CASE
WHEN INSTR(STRING, 'B') = 0 THEN INSTR(STRING, '|')-1
ELSE INSTR(STRING, 'B')-1
END) AS UP_TO_B
FROM cteData;
dbfiddle here
Assuming Bob Jarvis is correct in the assumption that "|" is also a delimiter (as seems likely) try:
-- define test data
with test as
( select '121/2808B|:6081' stg from dual union all
select 'OD308B|:6081_1:' from dual union all
select '008312100001200|:6081_1' from dual
)
-- execute extract
select regexp_substr(stg , '[^B|]+') val
from test ;

Extract city from the address column

enter image description hereWhat happens if if ship 3 and 4 are null, but ship2 is not null, that should be city state
Here is sample data in the picture.
I prefer the oldfashioned SUBSTR + INSTR combination which, if compared to Gordon's and Barbaros' suggestions, seems to be somewhat better as their queries return strings that don't even contain a comma, while the OP says
extract city from 1 letter until 1 comma
Here's a comparison:
SQL> with tab (addr) as
2 (
3 select 'RALEIGH, NC 27604-3229' from dual union all
4 select 'SUITE A' from dual union all
5 select 'COEUR D ALENE, ID 83815-8652' from dual union all
6 select '*O/S CITY LIMITS*' from dual
7 )
8 select addr,
9 substr(addr, 1, instr(addr, ',') - 1) littlefoot,
10 --
11 regexp_substr(addr, '[^,]+', 1, 1) gordon,
12 regexp_substr(addr,'[^,]+') barbaros
13 from tab;
ADDR LITTLEFOOT GORDON BARBAROS
---------------------------- --------------- -------------------- --------------------
RALEIGH, NC 27604-3229 RALEIGH RALEIGH RALEIGH
SUITE A SUITE A SUITE A
COEUR D ALENE, ID 83815-8652 COEUR D ALENE COEUR D ALENE COEUR D ALENE
*O/S CITY LIMITS* *O/S CITY LIMITS* *O/S CITY LIMITS*
SQL>
If you want the part before the first comma, you can use regexp_substr():
select regexp_substr(addr, '[^,]+', 1, 1)
Just use regexp_substr with [^,]+ pattern as below
select regexp_substr(address,'[^,]+') as city
from tab;
SQL Fiddle Demo 1
Or alternatively by creating an auxilary table :
with tab as
(
select 'RALEIGH, NC 27604-3229' as str from dual union all
select 'SALINAS, CA 93901' from dual union all
select 'DEPEW, NY 14043-2603' from dual
)
select regexp_substr(str,'[^,]+') as city
from tab;
SQL Fiddle Demo 2
If you don't want to use regexp, you can just use:
select substr(city,1,(instr(city,',')-1))
from mytable;

Replacing and removing leading characters

I have this query
Select Distinct EMPLOYEE_ID from TABLE
and this returns bunch of EMPLOYEE ID's with leading zero's if the person's ID starts with 000 then it should be an 'e' and if it's 00 then it should be a 'u'
so for example if I have
0041258 this should show in the result as u41258 and if I have
00041258 then this should show as e41258
Is there a way to trim and replace in more efficient way that using substr and Case statement? and if no can you please show me how to use the substr and the Case statement in this case
Well, you can use case:
select (case when employee_id like '000%' then 'e' || substr(employee_id, 4)
when employee_id like '00%' then 'u' || substr(employee_id, 3)
else employee_id
end)
I doubt there is a much more efficient method than this.
Option that uses nested regular expressions:
SQL> with test (id) as
2 (select '0041258' from dual union
3 select '00041258' from dual
4 )
5 select id,
6 regexp_replace(regexp_replace(id, '^000', 'e'), '^00', 'u') result
7 from test;
ID RESULT
-------- --------------------
00041258 e41258
0041258 u41258
SQL>
Assuming you need to write an update statement (to permanently change the id's):
update <table>
set employee_id = case when employee_id like '000%'
then 'e' || substr(employee_id, 4)
else 'u' || substr(employee_id, 3) end
where employee_id like '00%'
;