I have a column with name "data-description" which has entries like
Mumbai,Maharastra,India
London,London, Britain
Chandigarh,Haryana,India
Lahore, Punjab, Non-India
Each line describes the value of one data-description column.
Now I need to update another table which will have three columns which will have
<City> => <Citycode> ---> Every City
<Statename> => <Statename>
<Country> => <Country>
I have a table where a mapping between City and City-Code is made. Now I need to make another table with the three columsn Citycode, Statename, Country
How do I do this with a couple of SQl statements and without using any PL/SQL?
Also, The order may not be the same in rows. Like some rows have order City,State,County. Others may have the order State,Country,City.
you can use REGEXP_SUBSTR to extract information from your source column:
SQL> WITH my_data AS (
2 SELECT 'Mumbai,Maharastra,India' d FROM dual
3 UNION ALL SELECT 'London,London, Britain' d FROM dual
4 UNION ALL SELECT 'Chandigarh,Haryana,India' d FROM dual
5 UNION ALL SELECT 'Lahore, Punjab, Non-India' d FROM dual
6 )
7 SELECT regexp_substr(d, '[^, ]+', 1, 1) City,
8 regexp_substr(d, '[^, ]+', 1, 2) Statename,
9 regexp_substr(d, '[^, ]+', 1, 3) Country
10 FROM my_data;
CITY STATENAME COUNTRY
------------------------- ------------------------- -------------------------
Mumbai Maharastra India
London London Britain
Chandigarh Haryana India
Lahore Punjab Non-India
Related
This question already has answers here:
Oracle query to match all values in the list among all rows in table
(3 answers)
Closed last month.
Using Oracle SQL, If I have this dataset, how can I select only those records which has value of both Europe and America? In other words I don't wanna see Johnny Bravo on the report.
Name
Surname
Continent
Johnny
Bravo
America
Pier
Ruso
Europe
Pier
Ruso
America
Thank you
Here's one option; it expects that there are two distinct continents per name, where one of them is America and another Europe.
Johnny isn't returned as he has only one continent (America), and Mike isn't in result set as he has 3 continents (two of them are America and Europe, but - there are 3 continents in a table for that person):
Sample data:
SQL> with test (name, surname, continent) as
2 (select 'Johnny', 'Bravo', 'America' from dual union all
3 --
4 select 'Pier' , 'Ruso' , 'Europe' from dual union all
5 select 'Pier' , 'Ruso' , 'America' from dual union all
6 --
7 select 'Mike' , 'Tiger', 'Europe' from dual union all
8 select 'Mike' , 'Tiger', 'Asia' from dual union all
9 select 'Mike' , 'Tiger', 'America' from dual
10 )
Query:
11 select name, surname
12 from test
13 group by name, surname
14 having count(distinct continent) = 2
15 and min(continent) = 'America'
16 and max(continent) = 'Europe';
NAME SURNAME
------ ----------
Pier Ruso
SQL>
id city
1 London
2 Rome
3 London
4 Rome
Expected output like this:
London Rome
2 2
Using case expression...
How can I solve this query?
This is a standard aggregation + group by + having problem.
Sample data:
SQL> with test (id, city) as
2 (select 1, 'London' from dual union all
3 select 2, 'Rome' from dual union all
4 select 3, 'London' from dual union all
5 select 4, 'Rome' from dual union all
6 select 5, 'Zagreb' from dual
7 )
Query:
8 select city,
9 count(*) cnt
10 from test
11 group by city
12 having count(*) > 1;
CITY CNT
------ ----------
London 2
Rome 2
SQL>
What does case expression have to do with it?
You can get your output using conditional aggregation:
SELECT COUNT(CASE city WHEN 'London' THEN 1 END) AS London,
COUNT(CASE city WHEN 'Rome' THEN 1 END) AS Rome
FROM table_name
WHERE city IN ('London', 'Rome')
Which, for the sample data:
CREATE TABLE table_name (id, city) AS
SELECT 1, 'London' FROM DUAL UNION ALL
SELECT 2, 'Rome' FROM DUAL UNION ALL
SELECT 3, 'London' FROM DUAL UNION ALL
SELECT 4, 'Rome' FROM DUAL;
Outputs:
LONDON
ROME
2
2
However, in this case, it is unclear how to handle your requirement for repeated values if the values were not repeated.
fiddle
Have a table containing address details with Cities for which some contain numbers that indicate the City district:
ID
CITY
COUNTRY
1
Praha 4
CZE
2
Dublin 1
GBR
3
Budapest 3
HUN
4
Dublin
GBR
5
Praha 7
CZE
6
Budapest
HUN
Would like to extract all Cities that contain numbers but excluding Praha.
Tried a combination of WHERE with LIKE and NOT LIKE or != as well as subquery excluding Praha or entire Country 'CZE' but always end up with all the values containing numbers.
Thanks!
You can use:
SELECT *
FROM table_name
WHERE REGEXP_LIKE(city, '\s+\d+$')
AND city NOT LIKE 'Praha%'
Or, from Oracle 12, without (slow) regular expressions:
SELECT *
FROM table_name
WHERE TO_NUMBER(
SUBSTR(city, INSTR(city, ' ', -1))
DEFAULT NULL ON CONVERSION ERROR
) IS NOT NULL
AND city NOT LIKE 'Praha%'
Which, for the sample data:
CREATE TABLE table_name (ID, CITY, COUNTRY) AS
SELECT 1, 'Praha 4', 'CZE' FROM DUAL UNION ALL
SELECT 2, 'Dublin 1', 'GBR' FROM DUAL UNION ALL
SELECT 3, 'Budapest 3', 'HUN' FROM DUAL UNION ALL
SELECT 4, 'Dublin', 'GBR' FROM DUAL UNION ALL
SELECT 5, 'Praha 7', 'CZE' FROM DUAL UNION ALL
SELECT 6, 'Budapest', 'HUN' FROM DUAL;
Both output:
ID
CITY
COUNTRY
2
Dublin 1
GBR
3
Budapest 3
HUN
db<>fiddle here
I have 2 tables: SalesPeople and Customers that have snum and cnum as primary key respectively; both tables have city column as well.
Without using joins, we have to tell the names of customers and salespeople that belong to same city.
I have used nested queries to print the salespeople that belong to the city of customers, but cant figure out how to print customer names with this .
SELECT S.*
FROM SalesPeople S
WHERE City IN(
SELECT City
FROM Customers CX
);
How about this? (Disregard the fact that the WITH factoring clause doesn't exist in Oracle 9i (at least, I think so); you already have those tables).
Sample data:
SQL> with
2 salespeople (snum, city) as
3 (select 1, 'London' from dual union all
4 select 2, 'Paris' from dual union all
5 select 3, 'Rome' from dual
6 ),
7 customers (cnum, city) as
8 (select 100, 'Zagreb' from dual union all
9 select 101, 'Rome' from dual union all
10 select 102, 'Rome' from dual union all
11 select 103, 'Paris' from dual
12 )
Query:
13 select person_num
14 from (select snum as person_num, city from salespeople
15 union
16 select cnum, city from customers
17 )
18 where city = 'Rome';
PERSON_NUM
----------
3
101
102
SQL>
This question already has answers here:
split string into several rows
(3 answers)
Closed 6 years ago.
I have a string which as values as below:
Countries = USA, Canada, Italy
I would like to seperate them and display it as list like below
Countries
USA
Canada
Italy
How can I do this using SQL?
There are multiple solutions posted in the Splitting Delimited Strings topic of the Oracle documentation pages.
One is:
Sample Data:
CREATE TABLE table_name ( id, list ) AS
SELECT 1, 'a,b,c,d' FROM DUAL UNION ALL -- Multiple items in the list
SELECT 2, 'e' FROM DUAL UNION ALL -- Single item in the list
SELECT 3, NULL FROM DUAL UNION ALL -- NULL list
SELECT 4, 'f,,g' FROM DUAL; -- NULL item in the list
Query:
SELECT t.id,
v.COLUMN_VALUE AS value,
ROW_NUMBER() OVER ( PARTITION BY id ORDER BY ROWNUM ) AS lvl
FROM table_name t,
TABLE(
CAST(
MULTISET(
SELECT REGEXP_SUBSTR( t.list, '([^,]*)(,|$)', 1, LEVEL, NULL, 1 )
FROM DUAL
CONNECT BY LEVEL < REGEXP_COUNT( t.list, '[^,]*(,|$)' )
)
AS SYS.ODCIVARCHAR2LIST
)
) v;
Output:
ID ITEM LVL
---------- ------- ----------
1 a 1
1 b 2
1 c 3
1 d 4
2 e 1
3 (NULL) 1
4 f 1
4 (NULL) 2
4 g 3
You can use a regex_substr and a connect by
select regexp_substr( 'USA, Canada, Italy','[^,]+', 1, level) from dual
connect by regexp_substr('USA, Canada, Italy', '[^,]+', 1, level) is not null;