Display the city with the shortest and longest name - mysql

I'm doing a question where I have been told:
"Query the two cities in the table with the shortest and longest city names, as well as their respective lengths (i.e.: number of characters in the name). If there is more than one smallest or largest city, choose the one that comes first when ordered alphabetically."
I am running the following code, however it keeps saying my answer is wrong:
SELECT CITY, LEN FROM (
SELECT CITY, LENGTH(CITY) AS LEN, ROW_NUMBER() OVER (ORDER BY LEN, CITY ASC) as r
FROM STATION ) as a
WHERE r IN (1, (select count(*) from a))
Why does that not work?

Use ROW_NUMBER() twice to get the city with min and max length:
SELECT t.CITY, t.LEN
FROM (
SELECT CITY, LENGTH(CITY) LEN,
ROW_NUMBER() OVER (ORDER BY LENGTH(CITY), CITY) as rn1,
ROW_NUMBER() OVER (ORDER BY LENGTH(CITY) DESC, CITY) as rn2
FROM STATION
) t
WHERE 1 IN (t.rn1, t.rn2)
See a simplified demo.

You could also use
select a.CITY, t.max_len, b.CITY, t.min_len
from (
SELECT max(LENGTH(CITY)) max_len , min(LENGTH(CITY)) min_len
FROM STATION
) t
INNER JOIN STATION a ON a.LENGTH(CITY) = t.max_len
INNER JOIN STATION b ON b.LENGTH(CITY) = t.min_len

Try it as two separate query and join it by UNION ALL.
(SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY) asc, CITY asc
LIMIT 1)
UNION ALL
(SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY) desc, CITY asc
LIMIT 1)

Related

Select shortest and longest string

Is it possible to select the shortest and longest strings by characters in a table?
I have a CITY column of type VARCHAR(20) and I want to select the shortest and longest city names in alphabetical order by length.
I did like this
SELECT CITY,LENGTH(CITY) FROM STATION WHERE LENGTH(CITY) IN ( SELECT MAX(LENGTH(CITY)) FROM STATION UNION SELECT MIN(LENGTH(CITY)) FROM STATION ) ORDER BY CITY ASC;
When ordered alphabetically, Let the CITY names be listed as ABC, DEF, PQRS, and WXY, with the respective lengths 3,3,4, and 3. The longest-named city is obviously PQRS, but there are options for the shortest-named city; I have to select ABC because it comes first alphabetically.
My query ended up with all three CITY having length 3.
ABC 3 DEF 3 PQRS 4 WXY 3
The result of SELECT must be
ABC 3 PQRS 4
Anyway i got the answer
SELECT CITY,LENGTH(CITY)
FROM STATION
WHERE LENGTH(CITY) IN (
SELECT MAX(LENGTH(CITY))
FROM STATION
UNION
SELECT MIN(LENGTH(CITY))
FROM STATION
)
ORDER BY LENGTH(CITY) DESC,CITY ASC LIMIT 2;
I know you have chosen your answer already, but here is a shorter answer that might help.
This is using Microsoft MySQL Server but it can also be easily translated to any other type using the call LIMIT instead of TOP.
Shortest Length
SELECT TOP 1 CITY, LEN(CITY)
FROM STATION
ORDER BY LEN(CITY) ASC, CITY ASC;
Longest Length
SELECT TOP 1 CITY, LEN(CITY)
FROM STATION
ORDER BY LEN(CITY) DESC, CITY ASC;
Try these queries.
Longest City Name::
select CITY from STATION where char_length(CITY) = (select max(char_length(CITY)) from STATION)
Shortest City Name::
select CITY from STATION where char_length(CITY) = (select min(char_length(CITY)) from STATION)
I have tried this and found the solution for MySQL database query,
(SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY) ASC, CITY ASC LIMIT 1)
UNION
(SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY) DESC, CITY ASC LIMIT 1)
I think it is better to use LIMIT than row number.
I read the comment of Midhun Manohar above: https://stackoverflow.com/a/50813334/11129060
I'm kind of a newbie so these are easier for me to understand:
SELECT CITY, LENGTH(CITY)
FROM STATION
WHERE LENGTH(CITY) IN (
SELECT MAX(LENGTH(CITY))
FROM STATION
)
ORDER BY CITY ASC LIMIT 1;
SELECT CITY, LENGTH(CITY)
FROM STATION
WHERE LENGTH(CITY) IN (
SELECT MIN(LENGTH(CITY))
FROM STATION
)
ORDER BY CITY ASC LIMIT 1;
or another post seems to be easier: https://stackoverflow.com/a/41285068/11129060
select CITY,LENGTH(CITY) from STATION order by Length(CITY) asc, CITY limit 1;
select CITY,LENGTH(CITY) from STATION order by Length(CITY) desc, CITY limit 1;
I think you need union with subquery if I understand correctly :
select s.*
from station s
where length(city) in (select max(length(city))
from station
union
select min(length(city))
from station)
order by length(city);
SELECT CITY, LENGTH(CITY) FROM STATION ORDER BY LENGTH(CITY),CITY LIMIT 1;
SELECT CITY, LENGTH(CITY) FROM STATION ORDER BY LENGTH(CITY) DESC, CITY LIMIT 1;
The above code should easily work out and be easy to understand. The first query displays the shortest city name and its length. The second one outputs the longest.
please find this below query :
SELECT top 2 CITY,LEN(CITY)
FROM STATION
WHERE LEN(CITY) IN (
SELECT MAX(LEN(CITY))
FROM STATION
UNION
SELECT MIN(LEN(CITY))
FROM STATION
)
ORDER BY LEN(CITY) DESC,CITY ASC ;
I found this one simple:
SELECT CITY, LENGTH(CITY) FROM (SELECT CITY FROM STATION ORDER BY LENGTH(CITY) ASC, CITY ASC)
WHERE ROWNUM=1;
SELECT CITY, LENGTH(CITY) FROM (SELECT CITY FROM STATION ORDER BY LENGTH(CITY) DESC, CITY ASC)
WHERE ROWNUM=1;
Much cleaner way:
SELECT CITY, LENGTH(CITY) FROM STATION ORDER BY LENGTH(CITY) ASC, CITY ASC LIMIT 1;
SELECT CITY, LENGTH(CITY) FROM STATION ORDER BY LENGTH(CITY) DESC, CITY ASC LIMIT 1;
In mssql server, it should be this.
SELECT TOP 2 CITY, LEN(CITY) FROM STATION
WHERE LEN(CITY) IN (
SELECT MAX(LEN(CITY)) FROM STATION
UNION
SELECT MIN(LEN(CITY)) FROM STATION
)
ORDER BY LEN(CITY) DESC, CITY ASC;
SELECT CITY,LENGTH(CITY)
FROM STATION
WHERE LENGTH(CITY) IN (
SELECT MAX(LENGTH(CITY))
FROM STATION
UNION
SELECT MIN(LENGTH(CITY))
FROM STATION
)
ORDER BY LENGTH(CITY) DESC,CITY ASC LIMIT 2;
(SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY) ASC, CITY ASC LIMIT 1)
UNION
(SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY LENGTH(CITY) DESC, CITY DESC LIMIT 1);
This gives you result something like this:
ABC 3
PQRS 4
The answer can be simplified in this sql query below.
(select city, length(city) from station group by city order by length(city), city limit 1)
union
(select city, length(city) from station group by city order by length(city) desc, city desc limit 1)
For SQL Server
SELECT CITY,TXTLEN
FROM
(
SELECT RANK() OVER(ORDER BY CITY ASC) IDX,CITY ,LEN(CITY) TXTLEN FROM STATION
WHERE LEN(CITY) IN ( SELECT MIN (LEN(CITY)) FROM STATION)
UNION
SELECT RANK() OVER(ORDER BY CITY DESC) IDX,CITY ,LEN(CITY) TXTLEN FROM STATION
WHERE LEN(CITY) IN ( SELECT MAX (LEN(CITY)) FROM STATION)
) AS FIN WHERE IDX=1 ORDER BY TXTLEN
The following code works in Oracle SQL. All the above solutions did not work for Oracle SQL btw! You may add Union in between. But this runs fine as well!
SELECT * FROM
(SELECT city,LENGTH(city)
from station
order by Length(city), city)
WHERE rownum <= 1;
SELECT * FROM
(SELECT city,LENGTH(city)
from station
order by Length(city) desc)
WHERE rownum <= 1;
HERE IS ONE
WITH t1 AS (
SELECT MAX(LENGTH(city)) AS Max_length_city ,
MIN(LENGTH(city)) AS Min_length_city
FROM station
)
SELECT city,LENGTH(city)
FROM station
WHERE LENGTH(city)=(SELECT Max_length_city FROM t1) OR LENGTH(city)=(SELECT Min_length_city FROM t1)
ORDER BY LENGTH(city) DESC,city ASC LIMIT 2
Select CITY, LENGTH(CITY) FROM STATION
WHERE ID IN (
SELECT ID FROM(Select ID,CITY,CLEN,ROW_NUMBER() OVER(ORDER BY CLEN ASC) AS RW FROM(
Select ID,CITY,LENGTH(TRIM(CITY)) CLEN,
DENSE_RANK() OVER(PARTITION BY LENGTH(CITY) ORDER BY CITY)
rnk from STATION ORDER BY CITY) WHERE rnk =1 order by CLEN asc) WHERE RW =1
)
UNION ALL
Select CITY, LENGTH(CITY) FROM STATION
WHERE ID IN (
SELECT ID FROM(Select ID,CITY,CLEN,ROW_NUMBER() OVER(ORDER BY CLEN ASC) AS RW FROM(
Select ID,CITY,LENGTH(TRIM(CITY)) CLEN,
DENSE_RANK() OVER(PARTITION BY LENGTH(CITY) ORDER BY CITY)
rnk from STATION ORDER BY CITY) WHERE rnk =1 order by CLEN asc) WHERE RW = (SELECT
MAX(RW) FROM(Select ID,CITY,CLEN,ROW_NUMBER() OVER(ORDER BY CLEN ASC) AS RW FROM(
Select ID,CITY,LENGTH(TRIM(CITY)) CLEN,
DENSE_RANK() OVER(PARTITION BY LENGTH(CITY) ORDER BY CITY)
rnk from STATION ORDER BY CITY) WHERE rnk =1 order by CLEN asc))
)
You can use UNION operator
(SELECT CITY, MAX(LENGTH(CITY)) FROM STATION)
UNION
(SELECT CITY, MIN(LENGTH(CITY)) FROM STATION)
GROUP BY CITY ASC LIMIT 1;
More examples https://dev.mysql.com/doc/refman/8.0/en/union.html

How to calculate median in mysql by using case when

I have a table named station having a column LAT_N. I am trying to get the median of LAT_N.
So here is my query:
select
case when count(Lat_N)%2=0 then (select (Lat_N from station limit (1,ceil(count(Lat_N)/2))+ select (Lat_N from station limit (1,floor(count(Lat_N)/2)))))
else (Select Lat_N from station limit(1,floor(count(Lat_N)/2)+1))
end
from station;
Try following query:
SELECT avg(tmp1.LAT_N) as median_LAT FROM (
SELECT #rownum:=#rownum+1 as row_number, s.val
FROM station s, (SELECT #rownum:=0) r
ORDER BY s.LAT_N
) as tmp1,
(
SELECT count(*) as total_rows
FROM station s
) as tmp2
AND tmp1.row_number in ( floor((total_rows+1)/2), floor((total_rows+2)/2) );

selecting single record if multiple records are having same length

I am trying to solve this problem on HackerRank
I tried this query :
select city, length(city) from station
where length(city) = (select max(length(city)) from station)
or length(city) = (select min(length(city)) from station)
order by
length(city) ASC,city ASC;
After running the above query, I get the following result :
Amo 3
Lee 3
Roy 3
Marine On Saint Croix 21
My Problem is : I only want to select Amo & Marine On Saint Croix. Not others.
How to achieve this ?
Thanks in Advance
you can try selecting both min and max length cities with limit 1 and union it?
select city, length(city) from station
where length(city) = (select max(length(city)) from station)
Limit 1
UNION
select city, length(city) from station
where length(city) = (select min(length(city)) from station)
Limit 1
Here is the correct query that works:
(SELECT city, LENGTH(city) AS length FROM station
ORDER BY LENGTH(city), city
LIMIT 1) UNION
(SELECT city, LENGTH(city) AS length FROM station
ORDER BY LENGTH(city) DESC, city
LIMIT 1)

Len of Column query in SQL

I'm new to SQL thus the question.
So I've the following table with Id, City, State named Station.
And I need to Query the two cities in STATION with the shortest and longest CITY names, as well as their respective lengths (i.e.: number of characters in the name). If there is more than one smallest or largest city, choose the one that comes first when ordered alphabetically.
Can someone help me get started with this. I tried the len() function on city but it doesn't seem to work.
City with the shortest name:
SELECT City, CHAR_LENGTH(City) AS len
FROM STATION
ORDER BY CHAR_LENGTH(City) ASC, City
LIMIT 1
City with the longest name:
SELECT City, CHAR_LENGTH(City) AS len
FROM STATION
ORDER BY CHAR_LENGTH(City) DESC, City
LIMIT 1
You can combine them into a single statement with UNION ALL:
SELECT *
FROM (
SELECT City, CHAR_LENGTH(City) AS len
FROM STATION
ORDER BY CHAR_LENGTH(City) ASC, City
LIMIT 1
) shortest
UNION ALL (
SELECT City, CHAR_LENGTH(City) AS len
FROM STATION
ORDER BY CHAR_LENGTH(City) DESC, City
LIMIT 1
) longest
This worked for me:
(SELECT CITY, CHAR_LENGTH(CITY) FROM STATION ORDER BY CHAR_LENGTH(CITY) ASC LIMIT 1) UNION (SELECT CITY, CHAR_LENGTH(CITY) FROM STATION ORDER BY CHAR_LENGTH(CITY) DESC LIMIT 1)
Here is a single query which you can try:
SELECT City, CHAR_LENGTH(City) AS length, 'max char length' AS description
FROM yourTable
WHERE CHAR_LENGTH(City) = (SELECT MIN(CHAR_LENGTH(City)) FROM yourTable)
ORDER BY City
LIMIT 1
UNION
SELECT City, CHAR_LENGTH(City) AS length, 'min char length' AS description
FROM yourTable
WHERE CHAR_LENGTH(City) = (SELECT MAX(CHAR_LENGTH(City)) FROM yourTable)
ORDER BY City
LIMIT 1
Here's my crack at it. This is untested, but it will give you something to start off of. (Edit: Now it is tested and it works. The union idea is probably better, but this would be the alternative using subqueries).
SELECT
(SELECT City
FROM table
ORDER BY CHAR_LENGTH(City) DESC, City
LIMIT 1) AS longest,
(SELECT CHAR_LENGTH(City)
FROM table
ORDER BY CHAR_LENGTH(City) DESC, City
LIMIT 1) AS longest_length,
(SELECT City
FROM table
ORDER BY CHAR_LENGTH(City) ASC, City
LIMIT 1) AS shortest,
(SELECT CHAR_LENGTH(City)
FROM table
ORDER BY CHAR_LENGTH(City) ASC, City
LIMIT 1) AS shortest_length
FROM table
LIMIT 1
Hey got the same question of Hacker Rank :-P
Here is the solution:
select * from
(select city, length(city) from station where length(city) = (select min(length(city)) from station) order by 1 limit 1) as tmp1
union all
select * from
(select city, length(city) from station where length(city) = (select max(length(city)) from station) order by 1 limit 1) as tmp2
we cannot use limit and order by clause with UNION clause. Thus we need to take alias of the result from both query and apply UNION clause.
Hope this will help :-)
(select CITY,length(CITY)
from STATION
where length(CITY)=(select min(length(CITY)) from STATION)
order by city
LIMIT 1)
union
(select CITY,length(CITY)
from STATION
where length(CITY)=(select max(length(CITY)) from STATION)
order by city
LIMIT 1);
This may work also -
select first(CITY) ,len(first(CITY)) from STATION where CITY in (select CITY from STATION where len(CITY) in (SELECT MAX(LEN(CITY)) FROM STATION) order by CITY asc)
UNION
select first(CITY) ,len(first(CITY)) from STATION where CITY in (select CITY from STATION where len(CITY) in (SELECT MIN(LEN(CITY)) FROM STATION) order by CITY asc);
SELECT City, CHAR_LENGTH(City)
FROM STATION
ORDER BY CHAR_LENGTH(City) ASC, City
LIMIT 1;
SELECT City, CHAR_LENGTH(City)
FROM STATION
ORDER BY CHAR_LENGTH(City) DESC, City
LIMIT 1;
Try the above solution I reckon should solve your problem.
(select CITY,length(CITY)
from STATION
where length(CITY)=(select min(length(CITY)) from STATION)
order by city
LIMIT 1)
union
(select CITY,length(CITY)
from STATION
where length(CITY)=(select max(length(CITY)) from STATION)
order by city
LIMIT 1)

How to select rows that have a maximum value for a column

I'm doing this challenge on Hackerrank:
https://www.hackerrank.com/challenges/weather-observation-station-5
I'm a beginner on SQL and I'm trying to query all the rows that have a maximum value for a column, maximum that I can only obtain via MAX(). So I'm trying this:
SELECT CITY, LENGTH(CITY) AS citylength
FROM STATION
WHERE LENGTH(CITY) = (SELECT MIN(CITY) FROM STATION)
and I get errors.
I've looked up on google about sub-queries but I'm not accustomed enough to know exactly how it works, so I need your help guys.Thanks.
So to sum up, I need a query that can get the rows on a table that has a maximum value obtained via MAX() clause.
You are requested to find two different results:
The city with maximum length (and the first in the alphabet in case of a tie)
The city with minimum length (and the first in the alphabet in case of a tie)
This means two different queries, which you glue together with UNION ALL.
(
select concat(city, ' ', length(city))
from station
order by length(city), city limit 1
)
union all
(
select concat(city, ' ', length(city))
from station
order by length(city) desc, city limit 1
);
As Strawberry pointed out: You need the parentheses in order to place two ORDER BY clauses, one per query part. (Otherwise you can only place one ORDER BY clause at the end for the whole query.)
In your query you are comparing LENGTH(CITY), i.e. an integer holding the name's length and MIN(CITY), i.e. the city name itself, which cannot work of course. You would have to compare with MIN(LENGTH(CITY)). Then do the same for the maximum and then use UNION ALL. This doesn't solve the problem with ties, however, which the LIMIT query does.
This works without sub-queries
SELECT CITY, LENGTH(CITY)
FROM STATION
ORDER BY 2,1
LIMIT 1
This works :
SELECT CITY,LENGTH(CITY)
FROM STATION
WHERE LENGTH(CITY) = (SELECT MIN(LENGTH(CITY)) M FROM STATION);
This works correctly:
select city, length(city)
from station
where length(city) = (select min(length(city)) as m from station)
order by city ASC
limit 1;
(SELECT CONCAT(city,' ',LENGTH(city)) city, 'shortest' category FROM stations ORDER BY LENGTH(city),city LIMIT 1)
UNION ALL
(SELECT CONCAT(city,' ',LENGTH(city)), 'longest' FROM stations ORDER BY LENGTH(city) DESC,city LIMIT 1);
select TOP 1 concat(city, ' ' , len(city)) from station where len(city) = (select min(len(city)) from station) order by city asc;
select TOP 1 concat(city, ' ' , len(city)) from station where len(city) = (select max(len(city)) from station) order by city desc;
SELECT * FROM
(SELECT City, LENGTH(City) FROM STATION
ORDER BY LENGTH(City),city ASC)
WHERE ROWNUM <= 1
UNION ALL
SELECT * FROM
(SELECT City, LENGTH(City) FROM STATION
ORDER BY LENGTH(City) DESC)
WHERE ROWNUM <= 1;