Ordering Query for Country & City data for the scenario given - sql

My input data is below :
**Country city**
Australia Sydney
Australia melbourne
India Delhi
India Chennai
India Bangalore
Afghanistan Kabul
Output expected is:
Afghanistan
Kabul
Australia
melbourne
syndey
India
Bangalore
Chennai
Delhi
The data in both columns should be arranged alphabetically(both city level and country level) and result should be single column with above values. The country should be alphabetically ordered and the corresponding cities should go below them which should also be alphabetically ordered.
How can this be done without using an intermediate table in a single query?

You need a UNION ALL query to get one row per country and one row per city in your result:
select coalesce(city, country) as location
from
(
select distinct country, null as city from mytable
union all
select country, city from mytable
)
order by country, city nulls first;

This has a single table scan and also does not need to use UNION to get distinct results:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE cities ( Country, city ) AS
SELECT 'Australia', 'Sydney' FROM DUAL UNION ALL
SELECT 'Australia', 'melbourne' FROM DUAL UNION ALL
SELECT 'India', 'Delhi' FROM DUAL UNION ALL
SELECT 'India', 'Chennai' FROM DUAL UNION ALL
SELECT 'India', 'Bangalore' FROM DUAL UNION ALL
SELECT 'Afghanistan', 'Kabul' FROM DUAL;
Query 1:
SELECT value
FROM (
SELECT c.*,
country AS ctry,
ROW_NUMBER() OVER ( PARTITION BY Country ORDER BY city ) AS rn
FROM cities c
)
UNPIVOT( value FOR key IN ( Country AS 1, City AS 2 ) )
WHERE rn = 1 OR key = 2
ORDER BY ctry, rn, key
Results:
| VALUE |
|-------------|
| Afghanistan |
| Kabul |
| Australia |
| Sydney |
| melbourne |
| India |
| Bangalore |
| Chennai |
| Delhi |

Related

SQL How to access element of a different table?

I have this table [pets]
Animal
prev_store
curr_store
Cat
ABC
DEF
Dog
ABC
GHI
Fish
DEF
XYZ
Snake
XYZ
JKM
I also have this other table [pet_store]
Store
Country
ABC
England
DEF
Denmark
GHI
England
XYZ
Denmark
JKM
Denmark
I want to check for each animal in pets table, whether the prev_store and curr_store is in the same Country, and if so, make a record of the Country.
Country
Occurrences
England
1
Denmark
2
SELECT pet_store.Country, count(pet_store.Country)
FROM pet_store, pets
WHERE pets.prev_store = pet_store.Store
and pets.curr_store = pet_store.Store
GROUP BY pet_store.Country
Unsure about how I would then select the animals's Country in relevance to the prev and curr store.
You will have to use pets_store twice, in two roles, in the query:
WITH
-- your data, don't use in query ..
pets(Animal,prev_store,curr_store) AS (
SELECT 'Cat' ,'ABC','DEF'
UNION ALL SELECT 'Dog' ,'ABC','GHI'
UNION ALL SELECT 'Fish' ,'DEF','XYZ'
UNION ALL SELECT 'Snake','XYZ','JKM'
)
,
pets_store(Store,Country) AS (
SELECT 'ABC','England'
UNION ALL SELECT 'DEF','Denmark'
UNION ALL SELECT 'GHI','England'
UNION ALL SELECT 'XYZ','Denmark'
UNION ALL SELECT 'JKM','Denmark'
)
-- real query starts here ...
SELECT
prev_stores.country AS country
, COUNT(*) AS occurrences
FROM pets
JOIN pets_store prev_stores ON prev_store = prev_stores.store
JOIN pets_store curr_stores ON curr_store = curr_stores.store
WHERE prev_stores.country = curr_stores.country
GROUP BY prev_stores.country;
-- out country | occurrences
-- out ---------+-------------
-- out Denmark | 2
-- out England | 1

How to search a string inside a string in Oracle

I have a table A with columns Country ID ,Country. and data is like this
US United States
IN India
JP Japan
NP Nepal
etc .
I have different table B which has a column Country which mostly has free text data . Data is like
Texas United States
India KA
XYS Japan WYS
EverestNepal
XYZ
etc.
What i want is that if country column in Table B has a country matching from any column of country in Table A , it should return Country from Table A.
So for the example i gave
Table B has Texas United States --- there is a match in Table A with 'United States' : It should print United States
Table B has India KA ---- there is a match in Table A with 'India':it should print India
EverestNepal --- there is a match in Table A with 'Nepal': it should print Nepal
Table B has
and so on.
To summarize : If the exact match of country in Table B from anywhere in the string is found in Table A, it should print country from Table A
I dont think Like , IN , Substring will work in such situation
INSTR (line #17) is what you probably need.
SQL> with
2 ta (country_id, country) as
3 (select 'US', 'United States' from dual union all
4 select 'IN', 'India' from dual union all
5 select 'JP', 'Japan' from dual union all
6 select 'NP', 'Nepal' from dual
7 ),
8 tb (country) as
9 (select 'Texas United States' from dual union all
10 select 'India KA' from dual union all
11 select 'XYS Japan WYS' from dual union all
12 select 'EverestNepal' from dual union all
13 select 'XYZ' from dual
14 )
15 select b.country B_country,
16 a.country A_country
17 from ta a right join tb b on instr(b.country, a.country) > 0;
B_COUNTRY A_COUNTRY
------------------- -------------
Texas United States United States
India KA India
XYS Japan WYS Japan
EverestNepal Nepal
XYZ
SQL>
You can use like operator to join between the tables:
SELECT
A.COUNTRY
FROM
TABLE_A A
JOIN TABLE_B B ON ( A.COUNTRY LIKE '%'
|| B.COUNTRY
|| '%' );
Cheers!!

Check for an entry in SQL Server

-----------------------
country | city | ids
-----------------------
India Mumbai 1
India Chennai 2
India Kolkata 3
---------------------
USA New York 2
USA Utah 3
---------------------
I have given a sample from a table. From the table, I am trying to query all the countries without id 1. I wrote this(Country was not included in the Where condition since it needs to apply to all the countries of the table).
Select * from Countries
WHERE id<>1
I got this.
-----------------------
country | city | ids
-----------------------
India Chennai 2
India Kolkata 3
---------------------
USA New York 2
USA Utah 3
---------------------
But I need the output to contain only USA(which does not have id=1). Is there any workaround for this?
SELECT * from Countries WHERE country not in
(SELECT country from Countries WHERE id=1)
use NOT EXISTS
Select *
from Countries c
where not exists
(
select *
from Countries x
where x.country = c.country
and x.id = 1
)
You need to group by Country like below :
SELECT C.Country
FROM City
WHERE C.Country NOT IN
(SELECT country FROM City WHERE id=1)
SQL Fiddle Demo
OR
SELECT
C.Country
FROM
City C
GROUP BY C.Country
HAVING C.Country NOT IN
(
SELECT Country FROM City WHERE Id =1
)
SQL Fiddle Demo

Oracle Sql : distinct value in a specific field [duplicate]

This question already has answers here:
How to select records with maximum values in two columns?
(2 answers)
Closed 7 years ago.
I have the following table :
**Country Name Number**
us John 45
us Jeff 35
fr Jean 31
it Luigi 25
fr Maxime 23
ca Justin 23
This table is order by Number. I want to have a query that for each country give me the name with highest number :
**Country Name Number**
us John 45
fr Jean 31
it Luigi 25
ca Justin 23
I try to use distinct but I can't only make it on country if I want to print the all thing...
Have an idea ?'
EDIT :
The table is obtain by a subquery
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE Countries AS
SELECT 'us' AS Country, 'John' AS Name, 45 AS "Number" FROM DUAL
UNION ALL SELECT 'us' AS Country, 'Jeff' AS Name, 35 AS "Number" FROM DUAL
UNION ALL SELECT 'fr' AS Country, 'Jean' AS Name, 31 AS "Number" FROM DUAL
UNION ALL SELECT 'it' AS Country, 'Luigi' AS Name, 25 AS "Number" FROM DUAL
UNION ALL SELECT 'fr' AS Country, 'Maxime' AS Name, 23 AS "Number" FROM DUAL
UNION ALL SELECT 'ca' AS Country, 'Justin' AS Name, 23 AS "Number" FROM DUAL;
Query 1:
SELECT Country,
MAX( Name ) KEEP ( DENSE_RANK FIRST ORDER BY "Number" DESC ) AS "Name",
MAX( "Number" ) AS "Number"
FROM Countries
GROUP BY Country
Results:
| COUNTRY | Name | Number |
|---------|--------|--------|
| ca | Justin | 23 |
| fr | Jean | 31 |
| it | Luigi | 25 |
| us | John | 45 |
I do not have an Oracle db handy but I got this working in my SQL Server db and am pretty sure it will work in Oracle (meaning I think I am using ANSI sql which should work in most db's):
SELECT m.Country,m.Name,m.number
FROM mytable m
INNER JOIN (
select country, MAX(number) as number
FROM mytable GROUP BY Country
) AS tmp ON m.Country = tmp.Country and m.Number = tmp.number
ORDER BY m.Number DESC
This has the added benefit that it should give you records when you have two people in a given country that have the same number.
You didn't give us a table name so I just called it mytable.
Try below query:
SELECT Country, MAX(numbeer) FROM Table_Name GROUP BY Country
PFB updated query to include Name:
SELECT t1.* FROM table1 t1 INNER JOIN
(SELECT country, max(numbeer) as numbeer FROM table1 GROUP BY country) t2
ON t1.country=t2.country AND t1.numbeer=t2.numbeer;
Use row_number():
select t.Country, t.Name, t.Number
from (select t.*,
row_number() over (partition by country order by number desc) as seqnum
from table t
) t
where seqnum = 1;

Split data over multiple columns into rows (in SQL or SAS)

I have data in the following form:
Country City1 City2 City3 AverageTemperature
UK London Glasgow Manchester 15
Italy Rome Naples Venice 25
Germany Munich Berlin 20
USA New York 25
With either SQL or a SAS data step, I would like to get the data in this form:
Country City AverageTemperature
UK London 15
UK Glasgow 15
UK Manchester 15
Italy Rome 25
Italy Naples 25
Italy Venice 25
Germany Munich 20
Germany Berlin 20
USA New York 25
So that I have the data across individual rows. I have thought about doing this by looping over the three city columns where the city is not blank, but I'm not sure how to confidently do this - is it easily done with either SQL or SAS? Just a pointer would be greatly appreciated.
SELECT COUNTRY, City1, AverageTemperature FROM Table_Name
UNION ALL
SELECT COUNTRY, City2, AverageTemperature FROM Table_Name
UNION ALL
SELECT COUNTRY, City3, AverageTemperature FROM Table_Name
To get rows where City column is not null you can do something like this
SELECT COUNTRY, City1, AverageTemperature FROM Table_Name
WHERE City1 IS NOT NULL
UNION ALL
SELECT COUNTRY, City2, AverageTemperature FROM Table_Name
WHERE City2 IS NOT NULL
UNION ALL
SELECT COUNTRY, City3, AverageTemperature FROM Table_Name
WHERE City3 IS NOT NULL
Simple in a SAS Data Step
data out;
set in;
array cities[3] city1-city3;
format city $12.;
do i=1 to 3;
if compress(cities[i]) ^= "" then do;
city = cities[i];
output;
end;
end;
keep country city AverageTemperature;
run;
You can unpivot this using "relatively" standard SQL. Here is an approach that only requires scanning the data once:
select country, city, averagetemperatur
from (select t.country,
(case when n = 1 then t.city1
when n = 2 then t.city2
when n = 3 then t.city3
end) as city,
t.averagetemperature
from t cross join
(select 1 as n union all select 2 union all select 3) n
) t
where city is not null;
The exact syntax for creating the table with three rows (n) can vary depending on the database.
A macro loop should do the job:
%MACRO Cities ;
%DO N=1 %TO 3 ;
proc sql ;
create table Cities_&N as
select Country, City&N as City, AverageTemperature
from your_table_name_here
where City&N is not null ;
quit ;
%END ;
data Cities ;
set Cities_: ;
run ;
%MEND ;
%Cities ;