How to determine if a column has two equal vowels in SQL Server?
For example 'maria' has two 'a' characters.
select
*
from
hr.locations
where
state_province is null
and
city like '...' <-- ?
You want to look for strings with a vowel appearing multiple times. You already have city like '...'.
Now, you may have in mind somehing like city like '%[aeiou]%<the same vowel>%', and you wonder how to make this <the same vowel> work. It simply is not possible; such reference is not available in LIKE. Instead find the expression for a single vowel: city like '%a%a%'. Then use OR for the different vowels:
select *
from hr.locations
where state_province is null
and
(
city like '%a%a%' or
city like '%e%e%' or
city like '%i%i%' or
city like '%o%o%' or
city like '%u%u%'
);
If your city column is case sensitive, and you want to find 'Anna' in spite of one A being in upper case and the other in lower case, make this lower(city) like '%a%a%'.
If your intention is to find those entries that contain exactly two equal vowels:
One way to find out how often a certain character (in your case a vowel) appears in a string is to first take the length of the entire string.
As second step, replace your character by an empty string and build the length of the new string.
This will be the length without all occurences of this character.
If the entire length reduced by the new length is 2, this will mean the character occurs exactly two times in your string.
So, you can create a query repeating this idea for every vowel, something like this:
SELECT yourcolumn
FROM yourtable
WHERE
LEN (yourcolumn) - LEN(REPLACE(yourcolumn,'a','')) = 2
OR LEN (yourcolumn) - LEN(REPLACE(yourcolumn,'e','')) = 2
OR LEN (yourcolumn) - LEN(REPLACE(yourcolumn,'i','')) = 2
OR LEN (yourcolumn) - LEN(REPLACE(yourcolumn,'o','')) = 2
OR LEN (yourcolumn) - LEN(REPLACE(yourcolumn,'u','')) = 2;
If your intention is to find those entries that contain at least two equal vowels: Just replace the "=" by ">=" or use LIKE instead.
Try out here: db<>fiddle
Related
I have a name(the country) and a capital column inside my world table. I want to show only the name and capital that have the same number of characters. Like Greece and Athens that both equal 6 characters. I'm trying to use the LENGTH function, but unsure of what I'm doing wrong.
SELECT name, capital FROM world
WHERE LEN(name) = LEN(capital);
There is a redundant , between capital and FROM.
In SQL you use = to compare, and not ==.
Looks like the site that you provided supports LEN function in order to get the length of a string.
SELECT name, capital FROM world WHERE LEN(name) = LEN(capital);
You should not put comma(,) in front of "FROM" clause and you should use one equal to "=".
This should works -
SELECT name, capital FROM world WHERE LENGTH(name) = LENGTH(capital);
Assuming I have table that looks like this:
Id | Name | Age
=====================
1 | Jose | 19
2 | Yolly | 26
20 | Abby | 3
29 | Tara | 4
And my query statement is:
1) Select * from thisTable where Name <= '*Abby';
it returns 0 row
2) Select * from thisTable where Name <= 'Abby';
returns row with Abby
3) Select * from thisTable where Name >= 'Abby';
returns all rows // row 1-4
4) Select * from thisTable where Name >= '*Abby';
returns all rows; // row 1-4
5) Select * from thisTable where Name >= '*Abby' and Name <= "*Abby";
returns 0 row.
6) Select * from thisTable where Name >= 'Abby' and Name <= 'Abby';
returns row with Abby;
My question: why I got these results? How does the wildcard affect the result of query? Why don't I get any result if the condition is this Name <= '*Abby' ?
Wildcards are only interpreted when you use LIKE opterator.
So when you are trying to compare against the string, it will be treated literally. So in your comparisons lexicographical order is used.
1) There are no letters before *, so you don't have any rows returned.
2) A is first letter in alphabet, so rest of names are bigger then Abby, only Abby is equal to itself.
3) Opposite of 2)
4) See 1)
5) See 1)
6) This condition is equivalent to Name = 'Abby'.
When working with strings in SQL Server, ordering is done at each letter, and the order those letters are sorted in depends on the collation. For some characters, the sorting method is much easier to understand, It's alphabetical or numerical order: For example 'a' < 'b' and '4' > '2'. Depending on the collation this might be done by letter and then case ('AaBbCc....') or might be Case then letter ('ABC...Zabc').
Let's take a string like 'Abby', this would be sorted in the order of the letters A, b, b, y (the order they would appear would be according to your collation, and i don't know what it is, but I'm going to assume a 'AaBbCc....' collation, as they are more common). Any string starting with something like 'Aba' would have a value sell than 'Abby', as the third character (the first that differs) has a "lower value". As would a value like 'Abbie' ('i' has a lower value than 'y'). Similarly, a string like 'Abc' would have a greater value, as 'c' has a higher value than 'b' (which is the first character that differs).
If we throw numbers into the mix, then you might be surpised. For example the string (important, I didn't state number) '123456789' has a lower value than the string '9'. This is because the first character than differs if the first character. '9' is greater than '1' and so '9' has the "higher" value. This is one reason why it's so important to ensure you store numbers as numerical datatypes, as the behaviour is unlikely to be what you expect/want otherwise.
To what you are asking, however, the wildcard for SQL Server is '%' and '_' (there is also '^',m but I won't cover that here). A '%' represents multiple characters, while '_' a single character. If you want to specifically look for one of those character you have to quote them in brackets ([]).
Using the equals (=) operator won't parse wildcards. you need to use a function that does, like LIKE. Thus, if you want a word that started with 'A' you would use the expression WHERE ColumnName LIKE 'A%'. If you wanted to search for one that consisted of 6 characters and ended with 'ed' you would use WHERE ColumnName LIKE '____ed'.
Like I said before, if you want to search for one of those specific character, you quote then. So, if you wanted to search for a string that contained an underscore, the syntax would be WHERE ColumnName LIKE '%[_]%'
Edit: it's also worth noting that, when using things like LIKE that they are effected by the collations sensitivity; for example, Case and Accent. If you're using a case sensitive collation, for example, then the statement WHERE 'Abby' LIKE 'abb%' is not true, and 'A' and 'a' are not the same case. Like wise, the statement WHERE 'Covea' = 'Covéa' would be false in an accent sensitive collation ('e' and 'é' are not treated as the same character).
A wildcard character is used to substitute any other characters in a string. They are used in conjunction with the SQL LIKE operator in the WHERE clause. For example.
Select * from thisTable WHERE name LIKE '%Abby%'
This will return any values with Abby anywhere within the string.
Have a look at this link for an explanation of all wildcards https://www.w3schools.com/sql/sql_wildcards.asp
It is because, >= and <= are comparison operators. They compare string on the basis of their ASCII values.
Since ASCII value of * is 42 and ASCII values of capital letters start from 65, that is why when you tried name<='*Abby', sql-server picked the ASCII value of first character in your string (that is 42), since no value in your data has first character with ASCII value less than 42, no data got selected.
You can refer ASCII table for more understanding:
http://www.asciitable.com/
There are a few answers, and a few comments - I'll try to summarize.
Firstly, the wildcard in SQL is %, not * (for multiple matches). So your queries including an * ask for a comparison with that literal string.
Secondly, comparing strings with greater/less than operators probably does not do what you want - it uses the collation order to see which other strings are "earlier" or "later" in the ordering sequence. Collation order is a moderately complex concept, and varies between machine installations.
The SQL operator for string pattern matching is LIKE.
I'm not sure I understand your intent with the >= or <= stateements - do you mean that you want to return rows where the name's first letter is after 'A' in the alphabet?
I'm an absolute beginner at SQL. I do know how to use SQL commands that belong to Data Manipulation Language and Data Definition Language.
The name of the table is ways_tags
id,key,value,type
164931009,street,6th Main Road Ram Nagar (N) Extn,addr
The header represents the column names, I've printed just one row.
Here's what I want to accomplish:
Select observations that have type as addr and key as street.
In such observations, scan the characters of value column and check if the last 4 characters match Extn and replace it with Extension
Also, is there a way I can reduce size of the code, where it checks for TWO patterns instead of ONE?
In other words
You can replace what I'd like to accomplish on 2. with something like
In such observations, scan the characters of value column:
i. If last 4 characters in the value column is Extn replace with Extension.
ii.If last 2 characters in the value column is St. replace with Street.
I'm really sorry, but I just know the pseudocode and don't know how to incorporate regular expressions with normal SQL, and so I can't post anything to show that I've tried.
So eventually after performing the step,
164931009,street,6th Main Road Ram Nagar (N) Extension,addr
is the updated observation instead of
164931009,street,6th Main Road Ram Nagar (N) Extn,addr
Select observations that have type as addr and key as street.
… scan the characters of value column and check if the last 4 characters match Extn
WHERE type = 'addr'
AND key = 'street'
AND value LIKE '%Extn'
… and replace it with Extension
If "Extn" does not occur anywhere else in the value, this could be done with replace(), but in the general case, you have to extract all but the four last characters, and append the new value:
substr(value, 1, length(value) - 4) || 'Extension'
Then plug this into an UPDATE statement:
UPDATE ways_tags
SET value = substr(value, 1, length(value) - 4) || 'Extension'
WHERE type = 'addr'
AND key = 'street'
AND value LIKE '%Extn';
Doing two replacements in a single statement would be possible with a CASE expression, but would not reduce code size.
How can i query a column with Names of people to get only the names those contain exactly 2 “a” ?
I am familiar with % symbol that's used with LIKE but that finds all names even with 1 a , when i write %a , but i need to find only those have exactly 2 characters.
Please explain - Thanks in advance
Table Name: "People"
Column Names: "Names, Age, Gender"
Assuming you're asking for two a characters search for a string with two a's but not with three.
select *
from people
where names like '%a%a%'
and name not like '%a%a%a%'
Use '_a'. '_' is a single character wildcard where '%' matches 0 or more characters.
If you need more advanced matches, use regular expressions, using REGEXP_LIKE. See Using Regular Expressions With Oracle Database.
And of course you can use other tricks as well. For instance, you can compare the length of the string with the length of the same string but with 'a's removed from it. If the difference is 2 then the string contained two 'a's. But as you can see things get ugly real soon, since length returns 'null' when a string is empty, so you have to make an exception for that, if you want to check for names that are exactly 'aa'.
select * from People
where
length(Names) - 2 = nvl(length(replace(Names, 'a', '')), 0)
Another solution is to replace everything that is not an a with nothing and check if the resulting String is exactly two characters long:
select names
from people
where length(regexp_replace(names, '[^a]', '')) = 2;
This can also be extended to deal with uppercase As:
select names
from people
where length(regexp_replace(names, '[^aA]', '')) = 2;
SQLFiddle example: http://sqlfiddle.com/#!4/09bc6
select * from People where names like '__'; also ll work
I want to find all the names that start with numbers, weird chars (.,-#$, etc) and everything else that isn't a letter.
For example, i have 3 names: John, #1 John and 2John. What I want to get is the last 2 names. (and I don't know what weird chars the names can start, so it must be something like ![a-Z])..
I'm using postgresql.
SELECT *
FROM Table
WHERE name ~ '^[^a-zA-Z]'
If accented or non-Latin characters don't fall under your definition of "weird stuff", you may use:
SELECT *
FROM Table
WHERE name ~ '^[^[:alpha:]]'
PostgreSQL Manual: Pattern Matching