check comma separated field against comma separated value in mysql - mysql

A table field has values has 1,2,3 (comma seperated value) and a variable has 2,3. Now i need to check weather variable value is in table field using query along with another name field
user table
id name cat_id
-----------------
1 test 1,2,3
2 test1 3,4
3 test2 4
variable $value = 2, 3
Query : select * from user where name='test' and cat_id IN ('".$value."')
but for above query i get zero data
How to check if given id is exist in cat_id field and name exist in table

You can use a regex to check whether the value is contained in cat_id:
SELECT * FROM user WHERE name='test' AND cat_id REGEXP CONCAT('[[:<:]]', value, '[[:>:]]')
this will attempt to match value at any word boundary in cat_id, so for cat_id='1,2,3', values of (for example) '1,2', '2', '2,3' will match.
To put it in a string form (e.g. for PHP):
$sql = "SELECT * FROM user WHERE name='test' AND cat_id REGEXP CONCAT('[[:<:]]','" . $value. "', '[[:>:]]')";

Your cat_id field should contain only one id by row.
It's normal that your SQL request doesn't work currently because you're looking for cat_id 2 or 3 which SQL is not finding.
For example in your first row 1,2,3, for MySQL it's a string "1,2,3" and not an array of three ids.
If a name can be used by several cats maybe they should be the ones having a name_id.
And if a cat can have several names, and a name can have several cats, you should create a new table cats_names containing one name_id and one cat_id by row.

Related

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 compare two columns in mySql one of them Json

I have Two tables in mysql database and I want to compare two columns each of them in a different table first table name "oc_product_option_value" has column:
product_option_value_id
20
21
22
23
50
100
and second table "oc_cart" has cuolomn
option
{"20":"228","24":"229"}
I want compare two table and select data from first table where "product_option_value_id" in second table.
I tried:
SELECT * FROM oc_product_option_value
WHERE product_option_id IN
(SELECT REPLACE(REPLACE(REPLACE(REPLACE(OPTION,'{',''),'}',''),':',','),'"','')
as `option` FROM `oc_cart`)
and no result
* columns Structure
"product_option_value_id" is int
"option" is TEXT
Heum.. Not sure that it will do what you expect but I think it's a first step:
1/ Returns only rows wich have a matching value in second table (oc_cart)
SELECT *
FROM oc_product_option_value acpoa
JOIN oc_cart acc ON acc.option REGEXP concat('"', acpoa.product_option_value_id, '"');
Be careful about naming a column with a reserved MySQL word (option)
EDIT :
2/ If you want to display a "result" (final_kept_column) after this comparison in order to display "value_id" or "option" even if there's no matching value in oc_cart, you can try someting like this :
SELECT *,
CASE WHEN acc.option IS NULL
THEN acpoa.product_option_value_id
ELSE 0
END AS final_kept_column
FROM oc_product_option_value acpoa
LEFT JOIN oc_cart acc ON acc.option REGEXP concat('"', acpoa.product_option_value_id, '"');
Hope this help

search for substring in string mysql

i have two tables of businesses , i need to select(search) between tables by business name.
for example: if in one table i have business with name "Alcantara furniture network" with id 1, in another table the name "Alcantara furniture" with id 2 . the id 2 should be returned when searched from the first table with id 1.
i have tried to write query with LIKE but it is not helpful because it won't return the other business(id 2) . how can i search a substring in a string in mysql ?
You should change your like query to select what is common about the 2 values, i.e. 'Alacantara furniture':
select bussid,name
from tempBusiness
WHERE name LIKE '%Alcantara furniture%'
the string 'network' only appears in one of the names, so WHERE name LIKE '%Alcantara furniture network%' will only match one.

Select row from table where column value is subset of value passed in stored procedure

I have a table with columns and data something like this
+------+-------------------------+-------------+--------------+
| name | search_name | client_name | display_name |
+------+-------------------------+-------------+--------------+
| J&J | J&J | Johnson & Johnson | Janssen | J&J |
+------+-------------------------+-------------+--------------+
now i want to create a stored procedure that will pass a string lets say "Johnson & Johnson company" or "J&J company" and storproc should match the passed string with all the columns data and if any of the column value is subset of passed value so storproc should select that row or count of row(anything would be fine).
to be more precise if I pass "J&J company" in storproc and name column contain "J&J"(which is a subset of passed value) so storproc should return above row or count of row(anything would be fine).
PS : this is just a sample data original table contains more that 47000 rows so I can't do this in php level.
I have to do just opposite of 'LIKE' operator in mysql where in LIKE you pass a subset of string and table contains superset but in my case I have to pass a superset string and if table columns(any one) contains a subset that row should be returned.
Hope I have elaborated the problem enough, any help would be appreciable.
I took the concat from Gordon's answer, but I think this is what you're looking to do?
BEGIN
SELECT *
FROM tableName
WHERE #parameter LIKE concat('%', search_name, '%')
END
WHERE #parameter is your passed in string something like 'J&J Company' and search_name is your column name.
You can still do this with like, by concatenating the wildcards to the passed in parameter:
where name like concat('%', #parameter, '%') or
searchname like concat'%', #parameter, '%') or
. . .

Count and group non-empty values in MySQL

I need to count the non-empty (by which I mean a string containing at least 1 character) rows grouped by a particular ID. Eg. my data might look like this:
form_id mapping
1 'value_1'
1 ''
1 'value_2'
2 ''
2 NULL
3 'value_3'
and I want to count the non-empty values for each form, so I want the results to look like this:
form_id mapping_count
1 2
2 0
3 1
If the empty values were all NULL, I guess I could use
SELECT form_id, count(mapping) FROM table GROUP BY form_id
...but that would include zero-length strings in the count, which I don't want.
I could use a where clause to only return rows where a value exists in the mapping column, but I want to return the form IDs that have no mappings, so that is no good either.
I'm guessing I need a subquery of some sort, but am having trouble putting it together.
SELECT form_id, COUNT(NULLIF(TRIM(mapping), ''))
FROM mytable
GROUP BY
form_id
This will not count records that don't contains at least one non-whitespace character (this includes whitespace strings, empty strings and NULLs).
If a non-empty all-whitespace string is valid, use this:
SELECT form_id, COUNT(NULLIF(mapping, ''))
FROM mytable
GROUP BY
form_id