83

I want to query the list of CITY names from the table STATION(id, city, longitude, latitude) which have vowels as both their first and last characters. The result cannot contain duplicates.

For this is I wrote a query like WHERE NAME LIKE 'a%' that had 25 conditions, each vowel for every other vowel, which is quite unwieldy. Is there a better way to do it?

2
  • 1
    Ideas: regular expression or left()/right(). Commented Apr 14, 2016 at 15:30
  • 8
    Even though the problem is interesting per se, you should have changed table and field names to make it less explicitly about the question "Weather Observation Station 8" from hackerrank.com/challenges/weather-observation-station-8/problem, instead of just copying the question.
    – Vongo
    Commented Feb 28, 2020 at 16:11

35 Answers 35

140

You could use a regular expression:

SELECT DISTINCT city
FROM   station
WHERE  city RLIKE '^[aeiouAEIOU].*[aeiouAEIOU]$'
4
  • 11
    100%, regex is e definitely the way to go! Note, this syntax is MySQL. Commented Jan 27, 2018 at 23:03
  • what if there are just 2 characters in string ?? let's say 'ae' Commented Aug 7, 2021 at 14:20
  • 1
    SQL0104N An unexpected token "RLIKE" was found following "m station where city". Expected tokens may include: "LIKE". SQLSTATE=42601
    – Karen Goh
    Commented Feb 8, 2023 at 10:19
  • @KarenGoh that looks like a sql-server error. The question was about mysql
    – Mureinik
    Commented Feb 8, 2023 at 11:28
48

in Microsoft SQL server you can achieve this from below query:

SELECT distinct City FROM STATION WHERE City LIKE '[AEIOU]%[AEIOU]'

Or

SELECT distinct City FROM STATION WHERE City LIKE '[A,E,I,O,U]%[A,E,I,O,U]'

Update --Added Oracle Query

--Way 1 --It should work in all Oracle versions

SELECT DISTINCT CITY FROM STATION WHERE REGEXP_LIKE(LOWER(CITY), '^[aeiou]') and  REGEXP_LIKE(LOWER(CITY), '[aeiou]$');

--Way 2 --it may fail in some versions of Oracle

SELECT DISTINCT CITY FROM STATION WHERE REGEXP_LIKE(LOWER(CITY), '^[aeiou].*[aeiou]');

--Way 3 --it may fail in some versions of Oracle

SELECT DISTINCT CITY FROM STATION WHERE REGEXP_LIKE(CITY, '^[aeiou].*[aeiou]', 'i');
3
  • Is there any shorthand query like this for Oracle SQL?
    – Scott
    Commented Oct 8, 2017 at 18:25
  • I like this solution. I don't find the REGEXP necessary here. This seems the most simple/elegant
    – Microscone
    Commented Oct 4, 2018 at 12:53
  • In Microsoft SQL server you can achieve this from below query: select distinct city from station where city like '[aeiou]%';
    – sachind
    Commented Oct 30, 2019 at 6:52
17

Use a regular expression.

WHERE name REGEXP '^[aeiou].*[aeiou]$'

^ and $ anchor the match to the beginning and end of the value.

In my test, this won't use an index on the name column, so it will need to perform a full scan, as would

WHERE name LIKE 'a%a' OR name LIKE 'a%e' ...

I think to make it use an index you'd need to use a union of queries that each test the first letter.

SELECT * FROM table
WHERE name LIKE 'a%' AND name REGEXP '[aeiou]$'
UNION
SELECT * FROM table
WHERE name LIKE 'e%' AND name REGEXP '[aeiou]$'
UNION
SELECT * FROM table
WHERE name LIKE 'i%' AND name REGEXP '[aeiou]$'
UNION
SELECT * FROM table
WHERE name LIKE 'o%' AND name REGEXP '[aeiou]$'
UNION
SELECT * FROM table
WHERE name LIKE 'u%' AND name REGEXP '[aeiou]$'
5
  • Just pure curiousity.. is the engine clever enough to use indexes (instead of a full table scan)? Commented Apr 14, 2016 at 15:35
  • I don't think so, but you can check with EXPLAIN.
    – Barmar
    Commented Apr 14, 2016 at 15:37
  • 1
    I just checked on one of my tables, it didn't use an index.
    – Barmar
    Commented Apr 14, 2016 at 15:38
  • @Barmar What does .* mean. Can you please explain Commented Apr 15, 2020 at 11:57
  • . matches any character, * matches any number (including 0) of the preceding pattern. So .* matches anything. Go to www.regular-expression.info to read a tutorial on regexp.
    – Barmar
    Commented Apr 15, 2020 at 16:09
14

You can try one simple solution for MySQL:

SELECT DISTINCT city FROM station WHERE city REGEXP "^[aeiou].*[aeiou]$";
1
  • SQL0104N An unexpected token "REGEXP" was found following "M station WHERE city". Expected tokens may include: "IN". SQLSTATE=42601
    – Karen Goh
    Commented Feb 8, 2023 at 10:04
12

You may try this

    select city
    from station where SUBSTRING(city,1,1) in ('A','E','I','O','U') and 
    SUBSTRING(city,-1,1) in ('A','E','I','O','U');
1
  • Great way! One question, does it check for both capital AIEOU and small aieou or only the capital ones? Commented Jun 2, 2021 at 20:30
7

You could substring the first and last character and compare it with IN keyword,

WHERE SUBSTRING(NAME,1,1) IN (a,e,i,o,u) AND SUBSTRING(NAME,-1) IN (a,e,i,o,u) 
1
  • 3
    Your query may need single quotes for the characters inside the IN parenthesis. Commented May 18, 2017 at 21:51
5
SELECT distinct CITY 
FROM STATION 
where (CITY LIKE 'a%' 
    OR CITY LIKE 'e%' 
    OR CITY LIKE 'i%' 
    OR CITY LIKE 'o%'
    OR CITY LIKE 'u%'
) AND (CITY LIKE '%a' 
    OR CITY LIKE '%e'
    OR CITY LIKE '%i'
    OR CITY LIKE '%o'
    OR CITY LIKE '%u'
)
5

You can use the following regular expression and invert the result:

^[^aeiou]|[^aeiou]$

This works even if the input consists of a single character. It should work across different regex engines.

MySQL

SELECT city
FROM (
    SELECT 'xx' AS city UNION
    SELECT 'ax'         UNION
    SELECT 'xa'         UNION
    SELECT 'aa'         UNION
    SELECT 'x'          UNION
    SELECT 'a'
) AS station
WHERE NOT city REGEXP '^[^aeiou]|[^aeiou]$'

PostgreSQL

WHERE NOT city ~ '^[^aeiou]|[^aeiou]$'

Oracle

WHERE NOT REGEXP_LIKE(city, '^[^aeiou]|[^aeiou]$')`

SQL Server

No regular expression support. Use LIKE clause with square brackets:

WHERE city LIKE '[aeiou]%' AND city LIKE '%[aeiou]'
4

The below query will do for Orale DB:

select distinct(city) from station where upper(substr(city, 1,1)) in ('A','E','I','O','U') and upper(substr(city, length(city),1)) in ('A','E','I','O','U');
1
  • 1
    Thank you for this code snippet, which may provide some immediate help. A proper explanation would greatly improve its educational value by showing why this is a good solution to the problem, and would make it more useful to future readers with similar, but not identical, questions. Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply. Commented Jun 21, 2017 at 11:41
3

I hope this will help

select distinct city from station where lower(substring(city,1,1)) in ('a','e','i','o','u') and lower(substring(city,length(city),length(city))) in ('a','e','i','o','u') ;
3

Try this as I tried and it worked for me.

SELECT DISTINCT CITY 
FROM STATION  
WHERE CITY REGEXP '^[aeiou]' AND CITY REGEXP '[aeiou]$';
2

Try the following:

select distinct city 
from station 
where city like '%[aeuio]'and city like '[aeuio]%' Order by City;
0
2

The below one worked for me in MySQL:

SELECT DISTINCT CITY FROM STATION WHERE SUBSTR(CITY,1,1) IN ('A','E','I','O','U') AND SUBSTR(CITY,-1,1) in ('A','E','I','O','U');
1
  • SQL0138N A numeric argument of a built-in string function is out of range. SQLSTATE=22011
    – Karen Goh
    Commented Feb 8, 2023 at 10:09
2
SELECT DISTINCT CITY From STATION WHERE LOWER(SUBSTR(CITY,1,1)) IN ('a','e','i','o','u');

this will work in my sql

1

In MSSQL, this could be the way:

select distinct city from station 
where
right(city,1) in ('a', 'e', 'i', 'o','u') and left(city,1) in ('a', 'e', 'i', 'o','u') 
1

In Oracle:

SELECT DISTINCT city 
FROM station 
WHERE SUBSTR(lower(CITY),1,1) IN ('a','e','i','o','u') AND SUBSTR(lower(CITY),-1) IN ('a','e','i','o','u');
1

Try this for beginning with vowel

Oracle:

select distinct *field* from *tablename* where SUBSTR(*sort field*,1,1) IN('A','E','I','O','U') Order by *Sort Field*;
1

For MS access or MYSQL server

SELECT city FROM station
WHERE City LIKE '[aeiou]%'and City LIKE '%[aeiou]';
1
  • Welcome to Stack Overflow. As I write this comment, someone is probably already editing your post. Next time you'll be answering a question, consider encapsulating code into the code block.
    – FanaticD
    Commented May 12, 2017 at 11:31
1

you can also do a hard code like this, where you are checking each and every case possible, it's easy to understand for beginners

SELECT DISTINCT CITY 
FROM STATION
WHERE CITY LIKE 'A%A' OR CITY LIKE 'E%E' OR CITY LIKE 'I%I' OR CITY LIKE 'O%O' OR
CITY LIKE 'U%U' OR CITY LIKE 'A%E' OR CITY LIKE 'A%I' OR CITY LIKE 'A%O' OR 
CITY LIKE 'A%U' OR CITY LIKE 'E%A' OR CITY LIKE 'E%I' OR CITY LIKE 'E%O' OR 
CITY LIKE 'E%U' OR CITY LIKE 'I%A' OR CITY LIKE 'I%E' OR CITY LIKE 'I%O' OR 
CITY LIKE 'I%U' OR CITY LIKE 'O%A' OR CITY LIKE 'O%E' OR CITY LIKE 'O%I' OR 
CITY LIKE 'O%U' OR CITY LIKE 'U%A' OR CITY LIKE 'U%E' OR CITY LIKE 'U%I' OR 
CITY LIKE 'U%O'
1
  • FOR MS SQL --> in the where clause you can also add CITY LIKE '[a,e,i,o,u]%[a,e,i,o,u]' to save you from typing all possible combinations. add to the square brackets as you see fit. Commented Dec 5, 2018 at 6:54
1

You can use LEFT() and RIGHT() functions. Left(CITY,1) will get the first character of CITY from left. Right(CITY,1) will get the first character of CITY from right (last character of CITY).

DISTINCT is used to remove duplicates. To make the comparison case-insensitive, we will use the LOWER() function.

SELECT DISTINCT CITY
FROM STATION
WHERE LOWER(LEFT(CITY,1)) IN ('a', 'e', 'i', 'o', 'u') AND
      LOWER(RIGHT(CITY,1)) IN ('a', 'e', 'i', 'o', 'u')
1

Try this below code,

SELECT DISTINCT CITY
FROM   STATIOn
WHERE  city RLIKE '^[aeiouAEIOU].*.[aeiouAEIOU]$'
1
select distinct(city) from STATION 
where lower(substr(city, -1)) in ('a','e','i','o','u') 
      and lower(substr(city, 1,1)) in ('a','e','i','o','u');
1

If you are using Sequal server management studio (SSMS)the images shows that we are getting what exactly you have asked

SELECT DISTINCT CITY FROM STATION WHERE CITY LIKE '[a,e,i,o,u]%[a,e,i,o,u]';

2
  • that just messed up. but it works thanks Commented Dec 14, 2022 at 6:24
  • Messed up means? reply with your query please. Commented Dec 14, 2022 at 9:51
1

Following all queries work. :)

select distinct(t.city) from station t where lower(substr(t.city,1,1)) in ('a','e','i','o','u') and lower(substr(t.city,length(t.city),1)) in ('a','e','i','o','u');

select t.city from station t where lower(RIGHT(t.city,1)) in ('a','e','i','o','u') and lower(substr(t.city,1,1)) in ('a','e','i','o','u'); 

select t.city from station t where lower(RIGHT(t.city,1)) in ('a','e','i','o','u') and lower(left(t.city,1)) in ('a','e','i','o','u');
0

Both of the statements below work in Microsoft SQL SERVER

SELECT DISTINCT
    city
FROM
    station
WHERE
    SUBSTRING(lower(CITY), 1, 1) IN ('a', 'e', 'i', 'o', 'u')
    AND SUBSTRING(lower(CITY), LEN(CITY), 1) IN ('a', 'e', 'i', 'o', 'u');

SELECT DISTINCT
    City
FROM
    Station
WHERE
    City LIKE '[A, E, O, U, I]%[A, E, O, U, I]'
ORDER BY
    City;
0
SELECT DISTINCT city
FROM   station
WHERE  city RLIKE '^[^aeiouAEIOU]'OR city RLIKE'[^aeiouAEIOU]$'
3
  • Apologies! the above query results the cities that DO NOT have vowels as first or last character
    – Smita
    Commented Sep 2, 2016 at 12:57
  • Please try the following: SELECT DISTINCT city FROM station WHERE city RLIKE '^[aeiouAEIOU]' OR city RLIKE'[aeiouAEIOU]$'
    – Smita
    Commented Sep 2, 2016 at 12:57
  • Try posting answers to new questions. This was asked in 2014 and already has an accepted answer. The new questions need your attention more. Commented Sep 2, 2016 at 13:00
0

Try the following:

select distinct city from station where city REGEXP '^[aeiou]' and city REGEXP '[aeiou]$';
0

For oracle :

SELECT DISTINCT city
FROM   station
WHERE REGEXP_LIKE(city, '^[aeiou].*[aeiou]$','i') ;
0

Worked for me using simple left, right functions in MS SQL

select city from station where left(city,1) in ('a','e','i','o','u') and right(city,1) in ('a','e','i','o','u')
0

My simple solution

SELECT DISTINCT CITY
FROM STATION
WHERE CITY  LIKE '[a,e,i,o,u]%[a,e,i,o,u]';
1

Not the answer you're looking for? Browse other questions tagged or ask your own question.