MySQL Group by value in comma separated column [duplicate] - mysql

This question already has an answer here:
Search with comma-separated value mysql
(1 answer)
Closed 4 years ago.
I could use help with the database query I am trying to pull off. I have a table that has a word or phrase, a product id, a language id, and a version id. The version_id is a comma separated column, since the same word can be used in multiple versions and I tried to avoid adding another row with same data except for a different version.
The table currently looks like this
I am trying to get the COUNT of word per product, version, and language. The problem I am getting is seperating the version_id since it is a comma seperated column. Is there a way to get the count for all words in version 1, and version 2, separately?
I currently have this query, which works, but it does not separate by versions in a comma separated column.
SELECT COUNT( translation ) AS translations, fdp.name AS product, fdv.name AS version, fdl.name AS language, fdl.position
FROM `fdnfortidictionary_dictionary` AS `fdd`
LEFT JOIN `fdnfortidictionary_product` AS `fdp` ON fdd.product_id = fdp.id
LEFT JOIN `fdnfortidictionary_version` AS `fdv` ON fdd.version_id = fdv.id
LEFT JOIN `fdnfortidictionary_language` AS `fdl` ON fdd.language_id = fdl.id WHERE fdp.enable = 1
AND fdd.product_id IN (1,2)
AND CONCAT( ",", fdd.version_id, "," ) REGEXP ",(1|2|3|4|5),"
GROUP BY `language`,`version`,`product`,`position`
ORDER BY fdl.position ASC
The Result I am looking for is something like,

It seems like you might have some luck with FIND_IN_SET()
Probably, something like FIND_IN_SET(fdd.version_id, fdl.version_id) > 0

Related

Unable to find Comma Separated Values from Table in MySQL [duplicate]

I have a table say, ITEM, in MySQL that stores data as follows:
ID FEATURES
--------------------
1 AB,CD,EF,XY
2 PQ,AC,A3,B3
3 AB,CDE
4 AB1,BC3
--------------------
As an input, I will get a CSV string, something like "AB,PQ". I want to get the records that contain AB or PQ. I realized that we've to write a MySQL function to achieve this. So, if we have this magical function MATCH_ANY defined in MySQL that does this, I would then simply execute an SQL as follows:
select * from ITEM where MATCH_ANY(FEAURES, "AB,PQ") = 0
The above query would return the records 1, 2 and 3.
But I'm running into all sorts of problems while implementing this function as I realized that MySQL doesn't support arrays and there's no simple way to split strings based on a delimiter.
Remodeling the table is the last option for me as it involves lot of issues.
I might also want to execute queries containing multiple MATCH_ANY functions such as:
select * from ITEM where MATCH_ANY(FEATURES, "AB,PQ") = 0 and MATCH_ANY(FEATURES, "CDE")
In the above case, we would get an intersection of records (1, 2, 3) and (3) which would be just 3.
Any help is deeply appreciated.
Thanks
First of all, the database should of course not contain comma separated values, but you are hopefully aware of this already. If the table was normalised, you could easily get the items using a query like:
select distinct i.Itemid
from Item i
inner join ItemFeature f on f.ItemId = i.ItemId
where f.Feature in ('AB', 'PQ')
You can match the strings in the comma separated values, but it's not very efficient:
select Id
from Item
where
instr(concat(',', Features, ','), ',AB,') <> 0 or
instr(concat(',', Features, ','), ',PQ,') <> 0
For all you REGEXP lovers out there, I thought I would add this as a solution:
SELECT * FROM ITEM WHERE FEATURES REGEXP '[[:<:]]AB|PQ[[:>:]]';
and for case sensitivity:
SELECT * FROM ITEM WHERE FEATURES REGEXP BINARY '[[:<:]]AB|PQ[[:>:]]';
For the second query:
SELECT * FROM ITEM WHERE FEATURES REGEXP '[[:<:]]AB|PQ[[:>:]]' AND FEATURES REGEXP '[[:<:]]CDE[[:>:]];
Cheers!
select *
from ITEM where
where CONCAT(',',FEAURES,',') LIKE '%,AB,%'
or CONCAT(',',FEAURES,',') LIKE '%,PQ,%'
or create a custom function to do your MATCH_ANY
Alternatively, consider using RLIKE()
select *
from ITEM
where ','+FEATURES+',' RLIKE ',AB,|,PQ,';
Just a thought:
Does it have to be done in SQL? This is the kind of thing you might normally expect to write in PHP or Python or whatever language you're using to interface with the database.
This approach means you can build your query string using whatever complex logic you need and then just submit a vanilla SQL query, rather than trying to build a procedure in SQL.
Ben

IN query is not working group_concat in mysql subquery [duplicate]

This question already has answers here:
MySQL query finding values in a comma separated string
(11 answers)
Closed 5 years ago.
IN query is not working in sub_query of mysql
Please take look-:
SELECT (SELECT GROUP_CONCAT( text )
FROM course_intersted_in_list
WHERE id IN ( urd.interested_course )) as interested_course_text,
urd.*
from user_registration_data as urd
Here urd.interested_course have values like 1,2,3,4 for some users
user_registration_data table is like
id interested_course
1 1,2,3,4,5
2 1,4,5
course_intersted_in_list table is like
id interested_course
1 mbbs
2 dental
3 basic
Since the interested_course has comma separated ids, you can use find_in_set to search a value in csv string:
SELECT (SELECT GROUP_CONCAT( text )
FROM course_intersted_in_list
WHERE find_in_set(id, urd.interested_course)
) as interested_course_text,
urd.*
from user_registration_data urd;
Also, I recommend staying away from CSV data in RDBMS and normalize the data. that way you'll get a system that scales.
You can use MySQL FIND_IN_SET instead:
SELECT (SELECT GROUP_CONCAT( text )
FROM course_intersted_in_list
WHERE find_in_set(id, urd.interested_course)) as interested_course_text,
urd.*
from user_registration_data as urd
IN() doesn't work on table columns, only against a list inside ()

How do I find the records containing a comma-separated value? [duplicate]

This question already has answers here:
Find value in comma delimited string mysql
(3 answers)
Closed 6 years ago.
I've got a field in my database which contains comma-separated integers, for example:
"4,6,18,26,29,34"
I need to construct an SQL query which will return the record which contains a specific given integer, for example 6, so my current query is like this:
SELECT * FROM mytable WHERE CSVField LIKE "%,6,%"
I've surrounded the desired value with commas to avoid 6 matching 26 however it's obvious that my current query won't match against the first or last values in the field because the field doesn't start or end with a comma, so in the example above it'll never find 4 or 34.
How can I write my query so that it'll do what I want?
You can try:
SELECT * FROM mytable WHERE CSVField LIKE "%,6,%"
OR CSVField LIKE "6,%"
OR CSVField LIKE "%,6"
Hope you table is quite small though.
UPDATE
Following Mihai's post, try:
SELECT * FROM mytable WHERE FIND_IN_SET(CSVField,'6') > 0

Prepare mysql row for use in IN() clause

I need to find rows that contain a specific number in a set of numeric values that are stored in a table. I'm using the WHERE IN() function of mysql, but I'm having problems with the proper format.
Basically I have the following query:
SELECT id,category, text
FROM ws_cat
WHERE '11' IN (category)
The category field is a VARCHAR and looks like the following:
id category
1 11
2 12,11
3 1,13,9
So I need to find the rows with id 1 and 2 in this case. Unfortunately it doesn't work and I'm guessing it's because of the missing quotes, but all the ideas of reformating with QUOTES() or just changing the format of category to something like '12','11' wouldn't work either. Both would be possible for me as long as it works...
Use the FIND_IN_SET function:
SELECT id, category, text
FROM ws_cat
WHERE FIND_IN_SET('11', category) <> 0;

mysql in list only validates first id in list. maybe a blob issue [duplicate]

This question already has answers here:
MySQL query finding values in a comma separated string
(11 answers)
Closed 5 years ago.
I work with a system that used comma separated values as a one-2-many relation. It is stored in as a blob.
I try to use the MySQL IN (LIST), but only ends up with the rows where the uid is first in the list or only one in the list.
mytable
uid categories
1 24,25,26
2 25
3 22,23,25
4 25,27
run sql:
SELECT * FROM mytable WHERE 25 IN (categories)
Result:
uid categories
2 25
4 25,27
Missing (should have been selected but are not)
uid categories
1 24,25,26
3 22,23,25
Any idea why a string has to start with 25 and not just contain 25? I guess it is a string issue rather than an IN (LIST) issue
UPDATE - based on answers below:
When using th IN (LIST) on a blob, the blob is converted to an int and commas and "digits" are lost.
In stead use FIND_IN_SET(needle, haystack) that will work also on a blob containing comma separated values.
I think you are looking for FIND_IN_SET
SELECT * FROM mytable WHERE FIND_IN_SET(25,category)
This should give you your asnwer:
SELECT * FROM mytable WHERE CONCAT(',', categories, ',') LIKE '%,25,%'
But it would make more sense to create a connecting table, with each comma separated value as a new row.
What's happening is that MySQL is converting the blob to an integer (not a list of integers) for comparison. So '24,25,26' becomes the value 24. You can confirm this by running the query
SELECT CAST(categories AS signed) FROM mytable
This is not how IN (nor the blob data type) is meant to be used. Is there a reason you're not using another table for this?
Yes, it's astring issue. Your 'list' is just a string to mysql, meaning nothing.
You would have to use RegEx.
But you might think about normalizing your tables instead.