Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FIND_IN_SET() vs IN()

Tags:

mysql

People also ask

What is Find_in_set?

The FIND_IN_SET() function returns the position of a string within a list of strings.

What is a difference between where Find_in_set )> 0 and where Find_in_set?

Thus, we can observe that the main difference between FIND_IN_SET(…) and FIND_IN_SET(…)> 0 arises when the required string is present in the given list of strings. In this case, the FIND_IN_SET(…) function returns the index(starting from 1) of the required string whereas the FIND_IN_SET(…)>

How do I get comma separated values in SQL?

To check if value exists in a comma separated list, you can use FIND_IN_SET() function. Now you can insert some records in the table using insert command. Display all records from the table using select statement.


SELECT  name
FROM    orders,company
WHERE   orderID = 1
        AND companyID IN (attachedCompanyIDs)

attachedCompanyIDs is a scalar value which is cast into INT (type of companyID).

The cast only returns numbers up to the first non-digit (a comma in your case).

Thus,

companyID IN ('1,2,3') ≡ companyID IN (CAST('1,2,3' AS INT)) ≡ companyID IN (1)

In PostgreSQL, you could cast the string into array (or store it as an array in the first place):

SELECT  name
FROM    orders
JOIN    company
ON      companyID = ANY (('{' | attachedCompanyIDs | '}')::INT[])
WHERE   orderID = 1

and this would even use an index on companyID.

Unfortunately, this does not work in MySQL since the latter does not support arrays.

You may find this article interesting (see #2):

  • 10 things in MySQL (that won’t work as expected)

Update:

If there is some reasonable limit on the number of values in the comma separated lists (say, no more than 5), so you can try to use this query:

SELECT  name
FROM    orders
CROSS JOIN
        (
        SELECT  1 AS pos
        UNION ALL
        SELECT  2 AS pos
        UNION ALL
        SELECT  3 AS pos
        UNION ALL
        SELECT  4 AS pos
        UNION ALL
        SELECT  5 AS pos
        ) q
JOIN    company
ON      companyID = CAST(NULLIF(SUBSTRING_INDEX(attachedCompanyIDs, ',', -pos), SUBSTRING_INDEX(attachedCompanyIDs, ',', 1 - pos)) AS UNSIGNED)

attachedCompanyIDs is one big string, so mysql try to find company in this its cast to integer

when you use where in

so if comapnyid = 1 :

companyID IN ('1,2,3')

this is return true

but if the number 1 is not in the first place

 companyID IN ('2,3,1')

its return false


To get the all related companies name, not based on particular Id.

SELECT 
    (SELECT GROUP_CONCAT(cmp.cmpny_name) 
    FROM company cmp 
    WHERE FIND_IN_SET(cmp.CompanyID, odr.attachedCompanyIDs)
    ) AS COMPANIES
FROM orders odr

because the second query is looking for rows with the id's 1 OR 2 OR 3, the first query is looking for a one of the comma delimited values to exist in companyID,

and another problem here is you aren't joining the tables on a common key in your where so you are going to get a mutation of rows that = count(table1) * count(table2);

Your problem really exists with part 2 of my answer. (with your second query)