Intersect values on Mysql comma separated values - mysql

I've a table PriceList that has a VARCHAR column tags where I store a comma separated list of values.
An example of price list is:
ID
name
tags
1
Price list 1
tag1,tag2
2
Price list 2
tag3,tag4
What I want now is to query this table passing a list of tags (comma separated values). A priceList should be selected only if all of its tags are present in the query.
The tags I pass in the query could be more than the tags defined in the PriceList's tags column.
For example:
SELECT * FROM PriceList WHERE 'tag2,tag1,tag7' IN/FIND_IN_SET??? (tags)
In this example I expect the PriceList ID1 is retrieved because all of its tags are included in 'tag2,tag1,tag7' values.
I did not find any useful function in Mysql to accomplish to what I need to do. I know this is not the best design and this is acceptable because PriceList table is really really small (5/10 items).
The only idea that came to my mind is to store tags sorted alphabetically and to see if PriceList's tag column is a substring of my tags list.
What do you think? Do you have some hint?

Have a try on the following, it splits tags in the PriceList to multiple rows and count the matching rows against the input taglist
SELECT a.ID, MAX(a.tags), MAX(a.name)
FROM (
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(p.tags, ',', comma_index), ',', -1) AS tag, p.ID, LENGTH(p.tags) - LENGTH(REPLACE(p.tags, ',', '')) + 1 AS counts, p.tags, p.name
FROM (
SELECT 1 AS comma_index
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
) a
JOIN PriceList p
WHERE a.comma_index <= LENGTH(p.tags) - LENGTH(REPLACE(p.tags, ',', '')) + 1
) a
WHERE FIND_IN_SET(a.tag, 'tag2,tag1,tag7')
GROUP BY a.ID
HAVING COUNT(*) = MAX(a.counts)
The UNION part is an example, make sure the running numbers are more than the maximum number of tags in the table.
http://sqlfiddle.com/#!9/eb379d/1
But be sure it is not a good design to concat tags while individual tags are still in use, consider to have a table store tags separately.

Related

Unable to search single number and comma separated string in same query

I am trying to search on specific scenario from last 8 hours but unable to sort it out.
I need to get records from single table where I need to match a comma separated string against two columns.
-Both columns contain single values like 1 or comma separated values like 1,2,3
I need to get records where minimum one AND condition matches for both columns either for single value or comma separated value.
Here is my query
SELECT specialities, ids_origin, id, latitude, longitude
FROM `ep_restaurant`
where `specialities` in (2,4,5,32) and `ids_origin` in (106,154,3)
The record is fetching
http://prntscr.com/ntiao7
But it is matching when both columns have same whole set of comma separated values, I also need to get all of those where even single values from both columns match like 2,6 or 2,154 or whole comma separated string like (2,4,5,32) and (106,154,3) matched..
It is not my own database so i cannot change it. Please help me .Thanks.
MySQL has a useful function for such must-avoid use-case.
For example, if you have specialities table:
SELECT r.id, latitude, longitude, r.specialities
FROM ep_restaurant r
WHERE exists( SELECT 1
FROM specialities s
WHERE find_in_set(s.id, r.specialities)
AND s.id in(2,6)
)
OR exists( SELECT 1
FROM <Origins Table> o
WHERE find_in_set(o.<Column Id>, r.ids_origin)
AND o.<Column Id> in(106,154)
)

Return rows with more than one comma separated value in a string

I have a table called contacts and in that table there is a field called contact_type.
contact_type is varchar and stores comma separated values in a sting like this:
^Media^,^Historical^
However only a few rows out of thousands have more than one value stored and I need to to run a query that will return only the rows with more than one so if it stores just ^Historical^ then it will be ignored.
I’m pretty much stumped on how to build a query like this. I assume it will contain something like this:
SELECT LENGTH(#css) - LENGTH( REPLACE( #css, ',', '') ) + 1;
Basically you need to select the records where contact_type contains a comma
select * from your_table
where instr(contact_type, ',') > 0

Using distinct and order by in subquery

I am trying to get distinct 'productnumber' ordered by the 'createdate' but at the end I need only "productnumber" sorted by 'createdate' (I cannot use top as the 'productnumber' varies in a wide flexible range).
The distinct product number is needed to be concatenated with comma (,) for e.g.
123,245,787,875 (each number represents a productnumber)
The required query looks like somewhat (this query doesn't work and gives an error The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified):
SELECT stuff(
(
SELECT distinct ',' + productnumber
FROM Product
ORDER BY createdate
FOR XML path('')
)), 1, 1, '')
Could anyone help in how to go about to get the desired result.
As Mikael Eriksson suggested, using Group By clause solved the problem. Thanks Mikael
SELECT stuff((SELECT ',' + productnumber
FROM product a
ORDER BY a.createdate FOR xml path('')),1,1,'')
AS destn_str

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;

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