Check if a country code exists in a cell - mysql

I'm trying to check if a country code exists in a cell country before a user can add anything to the database. So, if a country code did not exist, he would not be able to add anything.
I'm storing country codes as comma separated values. The column type is VARCHAR.
"id" "rtype" "country"
"1" "0" "US,UK,SE,CA"
"2" "1" "US"
"3" "2" "UK"
I ran the following query, but this results in no rows. Where am going wrong here? The problem is, this query needs to run with comma separated values as well as single values.
select id, rtype from test where id=1 and country in('US')
Expected results
id | rType
1 | 0
select id, rtype from test where id=2 and country in('US')
Expected results
id | rType
2 | 0

Try this out:
SELECT id, rtype FROM test
WHERE FIND_IN_SET('US', country) > 0
This is how the FIND_IN_SET(str,strlist) function works:
Returns a value in the range of 1 to N if the string str is in the string list strlist consisting of N substrings. A string list is a string composed of substrings separated by “,” characters. [...] Returns 0 if str is not in strlist or if strlist is the empty string.

MySQL has a really nice Set Datatype. It is very efficient and can store till 64 distinct members of 255 values. I don't know if you could change your column type, but it would solve a lot of problems:
your column would be indexable
you wouldn't store duplicated values by mistake
it would be stored very efficiently
invalid values would be ignored (or error if in strict mode)
trailing spaces are removed
You'd search using the FIND_IN_SET function.

Since the country codes are the comma separated values , you can not directly use in .
You can you like instead.
select id, rtype from test where country like '%US%'

Related

How to find the longest matching string from a input string

A table, named strings, contains various strings, and unique id's:
Question is, how to write a query that takes an input string, and return the id of the longest matching (sub) string in the strings table?
The matching string, may, or may not be a substring of the input string. Comparison starts at string index 0.
Inputs and expected output:
INPUT -> OUTPUT
ABC -> 1
ABCD -> 2
ABCKK -> 1
ABCDDD -> 2
DAB -> NULL
CDE -> NULL
Doing this:
SET #theString = 'ABCBBB';
SELECT id FROM strings WHERE a_string LIKE #theString;
only returns the correct result when the input string exactly matches a string in the table, and don't work when the 'a_string' is a substring.
You can use:
select s.*
from strings s
where #theString regexp a_string
order by length(a_string) desc
limit 1;
In regards of using LIKE, you need to set the wildcards for it to work as the filter you want. If you are not required to set a variable, you can use the following query.
SELECT id FROM strings
WHERE a_string LIKE '%ABC%'
ORDER BY length(a_string) DESC LIMIT 1;
or if you need a variable, it can be done with the CONCAT function
SELECT id FROM strings
WHERE a_string LIKE CONCAT('%',#theString,'%')
ORDER BY length(a_string) DESC LIMIT 1;
This just is an alternative to #Gordon Linoff's answer.

How to check if a string in one field exist in every element of a comma separated field

I have a table which contains two fields. The first is name of type string. The second contains one or more strings separated by comma (but it can contain a single string with no commas at all)
I want to construct a query to know if the string in the name field does not exist in every comma separated strings in the names field.
Example 1:
---------------------------------------------------------
name names
---------------------------------------------------------
myname xmyname,myname,mynamey
All the comma separated strings contain the word myname. So the query shoudl not return this row.
But, Example 2:
---------------------------------------------------------
name names
---------------------------------------------------------
myname x,myname,mynamey
Should be returned. Because x does not contain myname.
The condition is that, if the string in the field name does not exists in each of the comma separated strings in the names field, then return the row.
This is not correct as this query will not return true in example 2 (which contains x which does not contain myname).
IMPORTANT NOTE:
1) There is not limit of how many commas there. It can be 0 commas or more. How to deal with this?
2) The strings are variables. It is not always the case that the string is myname. Each row contains a different string in the name field.
Try this regular expression:
where not concat(names, ',') regexp replace('^([^,]*{n}[^,]*,)*$', '{n}', name)
db-fiddle demo
How to read the pattern:
The inner pattern [^,]*{n}[^,]*, means
Any non comma character [^,] repeated any number of times (* means no times or multiple times).
followed by the value of the column name ({n} is a placeholder and will be replaced with the actual value using the replace() function)
followed by any non comma character [^,] repeated any number of times
followed by a comma
The outer pattern ^({inner_pattern})*$ means
Start of the string (^)
followed by the inner pattern repeated any number of times
followed by end of string ($)
To make this work, a comma is appended to the names column (concat(names, ',')), so that every element in the string ends with a comma.
The pattern will ensure, that any element in the comma separated string contains the value of the name column. Since you want the opposite result, we use where not ...
Assuming "myname" does not appear twice between two commas, you can count the commas and "myname"s:
where (length(names) - length(replace(names, ','))) >=
length(names) - length(replace(names, 'myname', '12345'))
This answer started off giving an incorrect REGEXP solution. But the best thing to do here would be to fix your data model, such that each name in the names column is actually on a separate row:
name | names
myname | xmyname
myname | myname
myname | mynamey
somename | x
somename | myname
somename | mynamey
Now we can do a simple aggregation query to answer your question:
SELECT name
FROM yourTable
GROUP BY name
HAVING COUNT(CASE WHEN names NOT LIKE CONCAT('%', name, '%') THEN 1 END) > 0;
Demo
You can approach this using the following SQL query
SELECT
name, names
FROM
`tablename`
WHERE
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1)
=
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
)/ LENGTH(name)
);
Explanation:-
This Will give you how many words are separated with ,
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1) -
Following is matching the name in each row and returning how many times it found
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
) / LENGTH(name)
)
DEMO

How to query something from an array using WHERE in sql

I tried the code below, but it does not work.
spark.sql("""SELECT categories, business_id
FROM business_data
WHERE categories = 'Ice Cream'
""").show(150, truncate=False)
It seems like there is a different way to query from an array but I cant figure it out.
This is what my data looks like.
Sample data:
Thank you
MySQL Specific:
FIND_IN_SET(str,strlist)
FROM DOCS:
Returns a value in the range of 1 to N if the string str is in the string list strlist consisting of N substrings. A string list is a string composed of substrings separated by , characters. If the first argument is a constant string and the second is a column of type SET, the FIND_IN_SET() function is optimized to use bit arithmetic. Returns 0 if str is not in strlist or if strlist is the empty string. Returns NULL if either argument is NULL. This function does not work properly if the first argument contains a comma (,) character.
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
So in your case...
spark.sql("""SELECT categories, business_id
FROM business_data
WHERE Find_In_set('Ice Cream',categories)>1
""").show(150, truncate=False)
Normally if you want to query something out of an Array you would use array_contains, as such:
SELECT business_id, categories
FROM business_data
WHERE array_contains(categories,'Ice Cream & Frozen Yogurt')

How to set the 'where' clause on a field with comma-seperated values?

I have a db table with a field with values stored in the value1,value2,value3,value4 format.
I want to find all the rows where this field contains a defined value, eg. value3.
How can I perform a query to search a value in a field like this one?
use FIND_IN_SET()
SELECT *
FROM tableName
WHERE FIND_IN_SET('value3', 'comma separated value here') > 0
SQLFiddle Demo
SOURCE
MySQL FIND_IN_SET
Description from MySQL Docs:
Returns a value in the range of 1 to N if the string str is in the
string list strlist consisting of N substrings. A string list is a
string composed of substrings separated by “,” characters. If the
first argument is a constant string and the second is a column of type
SET, the FIND_IN_SET() function is optimized to use bit arithmetic.
Returns 0 if str is not in strlist or if strlist is the empty string.
Returns NULL if either argument is NULL.
You can do this using like:
where concat(',', field, ',') like '%,value3,%'
SELECT *
FROM tableName
WHERE lower('comma separated values') LIKE 'value3'

Why does this search query return nothing?

I have this table under user_name='high'
function_description :
akram is in a date
test
akram is studying
test4
kheith is male
test3
I want a query that returns results of field that have at least an 'akram'
SELECT *
FROM functions
WHERE 'isEnabled'=1
AND 'isPrivate'=1
AND user_name='high'
AND function_description LIKE '%akram%'
and this returns absolutely nothing!
Why?
You are listing the column names as if they are strings. This is why it returns nothing.
Try this:
SELECT *
FROM functions
WHERE user_name='high'
AND function_description LIKE '%akram%'
edit: After trying to re-read your question... are isEnabled and isPrivate columns in this table?
edit2: updated.. remove those unknown columns.
You are comparing strings 'isEnabled' with integer 1, which likely leads to the integer being converted to a string, and the comparison then fails. (The alternative is that the string is converted to an integer 0 and the comparison still fails.)
In MySQL, you use back-quotes, not single quotes, to quote column and table names:
SELECT *
FROM `functions`
WHERE `isEnabled` = 1
AND `isPrivate` = 1
AND `user_name` = 'high'
AND `function_description` LIKE '%akram%'
In standard SQL, you use double quotes to create a 'delimited identifier'; in Microsoft SQL Server, you use square brackets around the names.
Please show the schema more carefully (column names, sample values, types if need be) next time.