w3resource

MySQL FIND_IN_SET() function

FIND_IN_SET() function

The MySQL FIND_IN_SET() function is a powerful tool used to locate the position of a substring within a comma-separated list of substrings. This function is particularly useful for searching and filtering data stored in a comma-delimited format. It returns the position of the substring if found, 0 if not found, and NULL if any argument is NULL.

This function is useful in -

  • Determining Position: Identify the exact position of a value within a comma-separated list.

  • Filtering data: You can use FIND_IN_SET() in WHERE clauses to filter data based on the presence or absence of a value.

  • Dynamic Value Checks: Compare values dynamically fetched from other tables or queries.

  • Conditional Updates: Update records conditionally based on the presence of a substring.

  • Data Validation: Validate if a particular value exists within a predefined list.

Syntax:

FIND_IN_SET (search string, string list)

Arguments:

Name Description
search string A string which is to be looked for in following a list of arguments.
string list List of strings to be searched if they contain the search string.

Syntax Diagram:

MySQL FIND_IN_SET() Function - Syntax Diagram

MySQL Version: 8.0

Pictorial Presentation:

MySQL FIND_IN_SET function

Basic Usage:

The following MySQL statement finds the search string ‘ank’ at the 2nd place within the string list. So it returns 2.

Code:


-- The following SQL query uses the FIND_IN_SET() function to find the position of the string 'ank' within a comma-separated list of strings.
SELECT FIND_IN_SET('ank', 'b,ank,of,monk');

Explanation:

  • This SQL query calls the FIND_IN_SET() function to search for the substring 'ank' within the comma-separated list 'b,ank,of,monk'.

  • The function returns the position of 'ank' in the list, which is 2 in this case because 'ank' is the second element in the list.

  • If the substring were not found, the function would return 0. If any argument were NULL, the function would return NULL.

Output:

mysql> SELECT FIND_IN_SET('ank','b,ank,of,monk'); 
+------------------------------------+
| FIND_IN_SET('ank','b,ank,of,monk') |
+------------------------------------+
|                                  2 | 
+------------------------------------+
1 row in set (0.00 sec)
Filtering Data in WHERE Clause:

Sample table: fun_n_veg


Code:


-- The following SQL query selects all columns from the table 'fru_n_veg'
-- where the string 'Cabbage' is found within the comma-separated values of the 'pkt_desc' column.
SELECT * FROM fru_n_veg WHERE FIND_IN_SET('Cabbage', pkt_desc);

Output:

item_id|weight|category  |pkt_desc                  |
-------+------+----------+--------------------------+
      5|  1500|Vegetables|Cabbage, Carrot, Broccoli |
      8|  2500|Vegetables|Cabbage, Eggplant, Pumpkin|

This will return all rows where the vegetable 'Cabbage' is found in the pkt_desc column.

MySQL FIND_IN_SET with other function:

The following MySQL statement find the search string as defined first 7 characters from aut_name column from the table author within the given string as specified in the argument and retrieves all columns from the concern rows.

Sample table: author


Code:


-- The following SQL query selects all columns from the table 'author'
-- where the first 7 characters of the 'aut_name' column match any of the
-- comma-separated values in the specified string 'William,steven,jung,angalo'.
SELECT * 
FROM author 
WHERE FIND_IN_SET(left(aut_name,7),'William,steven,jung,angalo') > 0;

Explanation:

  • This SQL query retrieves all rows and columns from the author table where the first 7 characters of the aut_name column match any of the names in the comma-separated list 'William,steven,jung,angalo'.

  • The LEFT(aut_name, 7) function extracts the first 7 characters of aut_name, and FIND_IN_SET() checks if this substring is present in the specified list.

Output:

+--------+-----------------+---------+-----------+
| aut_id | aut_name        | country | home_city |
+--------+-----------------+---------+-----------+
| AUT001 | William Norton  | UK      | Cambridge | 
| AUT002 | William Maugham | Canada  | Toronto   | 
| AUT003 | William Anthony | UK      | Leeds     | 
+--------+-----------------+---------+-----------+
3 rows in set (0.13 sec)
Using a specific value and condition:

Sample table: fun_n_veg


Code:


-- The following SQL query selects all columns from the table 'fru_n_veg'
-- where the 'category' column has the value 'Fruits' and
-- the string 'Guava' is present in the 'pkt_desc' column.
SELECT * 
FROM fru_n_veg 
WHERE category = 'Fruits' 
AND FIND_IN_SET('Guava', pkt_desc);

Explanation:

  • This SQL query retrieves all rows and columns from the fru_n_veg table where the category column is 'Fruits' and the pkt_desc column contains the value 'Guava' within its comma-separated list of items.

Output:

item_id|weight|category|pkt_desc               |
-------+------+--------+-----------------------+
      1|   500|Fruits  |Guava, Papaya, Pear    |
      2|   500|Fruits  |Guava, Watermelon, Pear|

This will return items from the 'Fruits' category where the item 'Guava' found in their pkt_desc column.

Using Multiple Values:

Sample table: fun_n_veg


Code:


-- The following SQL query selects all columns from the table 'fru_n_veg'
-- where the string 'Guava' is present in the 'pkt_desc' column or
-- the string 'Grapes' is present in the 'pkt_desc' column.
SELECT * 
FROM fru_n_veg 
WHERE FIND_IN_SET('Guava', pkt_desc) 
OR FIND_IN_SET('Grapes', pkt_desc);

Explanation:

  • This SQL query retrieves all rows and columns from the fru_n_veg table where the pkt_desc column contains either 'Guava' or 'Grapes' within its comma-separated list of items.

Output:

item_id|weight|category|pkt_desc                 |
-------+------+--------+-------------------------+
      1|   500|Fruits  |Guava, Papaya, Pear      |
      2|   500|Fruits  |Guava, Watermelon, Pear  |
      4|  1000|Fruits  |Grapes, pear, Watermelon |

This will return rows which contains either 'Guava' or 'Grapes' in their pkt_desc column.

Using Dynamic Values:

Sample table: fun_n_veg


Sample table: items


Code:


-- The following SQL query selects all columns from the 'fru_n_veg' table
-- where the 'pkt_desc' column contains an item name fetched from the 'items' table.
-- Specifically, it looks for the item name associated with 'item_code' 2.
SELECT * 
FROM fru_n_veg 
WHERE FIND_IN_SET((SELECT item_name FROM items WHERE item_code = 2), pkt_desc);

Explanation:

  • This SQL query retrieves all rows and columns from the fru_n_veg table where the pkt_desc column contains the item name corresponding to item_code 2 in the items table.

  • The subquery (SELECT item_name FROM items WHERE item_code = 2) fetches the item name which is then used by FIND_IN_SET to check its presence in the pkt_desc column of fru_n_veg.

Output:

item_id|weight|category  |pkt_desc                  |
-------+------+----------+--------------------------+
      5|  1500|Vegetables|Cabbage, Carrot, Broccoli |
      8|  2500|Vegetables|Cabbage, Eggplant, Pumpkin|

This will return pkt_desc which contain the items specified by item_code 2 in their item_code column, with the item name fetched from the items table.

Updating Records Based on List Membership:

Sample table: fun_n_veg


Code:


-- The following SQL query updates the 'weight' column to 400
-- for rows in the 'fru_n_veg' table where the 'pkt_desc' column
-- contains the substring 'Dates'.
UPDATE fru_n_veg 
SET weight = 400 
WHERE FIND_IN_SET('Dates', pkt_desc);

Explanation:

  • This SQL query updates the weight column to 400 for all rows in the fru_n_veg table where the pkt_desc column contains the item 'Dates'.

  • It uses the FIND_IN_SET function to check if 'Dates' is present in the comma-separated list of items in the pkt_desc column.

The table have been updated. The data shows, in the item_id 6 row, the weight column have been updated by 400 for the pkt_desc 'Dates', which was 250.

item_id|weight|category  |pkt_desc                  |
-------+------+----------+--------------------------+
      1|   500|Fruits    |Guava, Papaya, Pear       |
      2|   500|Fruits    |Guava, Watermelon, Pear   |
      3|  1000|Vegetables|Potato, Onion, Ginger     |
      4|  1000|Fruits    |Grapes, pear, Water melon |
      5|  1500|Vegetables|Cabbage, Carrot, Broccoli |
      6|   400|Dry Fruits|Dates, Almond, Dry fig    |
      7|   400|Dry Fruits|Walnuts, Almond, Cashew   |
      8|  2500|Vegetables|Cabbage, Eggplant, Pumpkin|
Difference between LOCATE() and FIND_IN_SET() Function

When using LOCATE() function for integers, suppose we need 1 to return from LOCATE() if integer 3 is in the set '1,2,3,4,5,..' the following MySQL commands can be written :

Code:


-- The following SQL query checks if the number 3 is present
-- in the comma-separated string '1,2,3,4,5,6,7,8,9' using the LOCATE() function.
-- If the number 3 is found, it returns 1. Otherwise, it returns 0.
SELECT IF(LOCATE(3,'1,2,3,4,5,6,7,8,9') > 0, 1, 0);

Explanation:

  • This SQL query uses the LOCATE function to check if the number 3 is present in the string '1,2,3,4,5,6,7,8,9'.

  • If the number 3 is found (i.e., LOCATE returns a position greater than 0), the IF function returns 1.

  • Otherwise, it returns 0.

Output:

mysql> SELECT IF(LOCATE(3,'1,2,3,4,5,6,7,8,9')>0,1,0);
+-----------------------------------------+
| IF(LOCATE(3,'1,2,3,4,5,6,7,8,9')>0,1,0) |
+-----------------------------------------+
|                                       1 | 
+-----------------------------------------+
1 row in set (0.06 sec)

The above command working rightly because the set contains the number 3.

LOCATE() Misinterpreting Integers:

Code:


-- This SQL query checks if the number 3 is present in the comma-separated string '11,12,13,14,15' using the LOCATE() function.
-- LOCATE() returns the position of the first occurrence of the substring '3'.
-- If the substring '3' is found in the string, LOCATE() will return a position greater than 0, 
-- and the IF function will return 1. If not found, LOCATE() returns 0, and the IF function will return 0.
SELECT IF(LOCATE(3, '11,12,13,14,15') > 0, 1, 0);

Explanation:

  • This SQL query uses the LOCATE function to search for the number 3 in the string '11,12,13,14,15'.

  • Even though the number 3 is part of 13 in the string, LOCATE treats the input as a substring and thus returns a position greater than 0.

  • The IF function then returns 1, indicating that the substring '3' is found, even though it is part of a larger number.

Output:

mysql> SELECT IF(LOCATE(3,'11,12,13,14,15')>0,1,0);
+--------------------------------------+
| IF(LOCATE(3,'11,12,13,14,15')>0,1,0) |
+--------------------------------------+
|                                    1 | 
+--------------------------------------+
1 row in set (0.02 sec)

Here we see from above example that, the 3 not present as a number three(3) in the given set, though the LOCATE() returns 1, because LOCATE() treate the given set as a string but not a comma seperated value, and the 3 present in the number 13.

Using FIND_IN_SET() Correctly:

To avoid this type of situation you can use the FIND_IN_SET() function. Here is the example below -

Code:


-- This SQL query checks if the number 3 is present in the comma-separated string '11,12,13,4,5,6,7,8,9' using the FIND_IN_SET() function.
-- FIND_IN_SET() returns the position of the string '3' within the comma-separated list.
-- If '3' is found, FIND_IN_SET() will return a position greater than 0, 
-- and the IF function will return 1. If '3' is not found, FIND_IN_SET() returns 0, and the IF function will return 0.
SELECT IF(FIND_IN_SET(3, '11,12,13,4,5,6,7,8,9') > 0, 1, 0);

Explanation:

  • This SQL query uses the FIND_IN_SET function to search for the number 3 in the comma-separated string '11,12,13,4,5,6,7,8,9'.

  • FIND_IN_SET looks for exact matches of '3' as a separate item in the list.

  • Since '3' is present as a separate item, FIND_IN_SET returns its position (greater than 0), and the IF function returns 1 to indicate that '3' was found.

Output:

mysql> SELECT IF(FIND_IN_SET(3,'11,12,13,4,5,6,7,8,9')>0,1,0);
+-------------------------------------------------+
| IF(FIND_IN_SET(3,'11,12,13,4,5,6,7,8,9')>0,1,0) |
+-------------------------------------------------+
|                                               0 | 
+-------------------------------------------------+
1 row in set (0.05 sec)

So, LOCATE() function is very much suitable for string but not as much suitable for integer.

Performance Considerations:
  • Indexing: FIND_IN_SET() does not utilize indexes, which can lead to slower performance on large datasets. Consider alternative methods or restructuring data for optimization.

  • Large Data Sets: For large data sets, using FIND_IN_SET() might cause performance issues. Use it judiciously and consider data restructuring if performance becomes a concern.
Common Pitfalls and Troubleshooting:
  • Null Values: If any argument is NULL, the function returns NULL. It should be ensure that our inputs are not NULL.

  • Empty Strings: An empty search string or list can lead to unexpected results. We should handle these cases appropriately in our code.

Frequently Asked Questions (FAQ) - MySQL FIND_IN_SET() function

1. What is the MySQL FIND_IN_SET() function?

  • The MySQL FIND_IN_SET() function is used to determine the position of a substring within a comma-separated list of substrings. It is useful for searching and filtering data that is stored in a comma-delimited format.

2. What does MySQL FIND_IN_SET() return?

  • Position: The function returns the position of the substring within the list, where positions start at 1.

  • 0: If the substring is not found in the list.

  • NULL: If any argument provided to the function is NULL.

3. What happens if the search string is not found?

  • The function returns 0.

4. Can MySQL FIND_IN_SET() handle multiple delimiters?

  • No, it only works with comma-separated lists.

5. How does MySQL FIND_IN_SET() compare with LOCATE()?

  • FIND_IN_SET() is better for comma-separated lists, while LOCATE() is more suitable for general substring searches.

Video Presentation:

All String Functions (Slides presentation)

Previous: FIELD
Next: FORMAT



Become a Patron!

Follow us on Facebook and Twitter for latest update.

It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.

https://www.w3resource.com/mysql/string-functions/mysql-find_in_set-function.php