Like you said, this isn't the way to do it. But since it's an imperfect world:
Assuming a database structure like so:
+-PRODUCTS---------+ +-CUSTOMERS---------+------------+
| ID | productName | | ID | customerName | productIDs |
+----+-------------+ +----+--------------+------------+
| 1 | Foo | | 1 | Alice | 1;2 |
+----+-------------+ +----+--------------+------------+
| 2 | Bar | | 2 | Bob | 2;3 |
+----+-------------+ +----+--------------+------------+
| 3 | Baz | | 3 | Charlie | |
+----+-------------+ +----+--------------+------------+
Then a query like this:
SELECT customers.*,
GROUP_CONCAT(products.id) AS ids,
GROUP_CONCAT(productName) AS names
FROM customers
LEFT JOIN products
ON FIND_IN_SET(products.id, REPLACE(productIDs, ";", ","))
GROUP BY customers.id
Would return:
+-RESULT------------+------------+-----+---------+
| ID | customerName | productIDs | ids | names |
+----+--------------+------------+-----+---------+
| 1 | Alice | 1;2 | 1,2 | Foo,Bar |
+----+--------------+------------+-----+---------+
| 2 | Bob | 2;3 | 1,2 | Bar,Baz |
+----+--------------+------------+-----+---------+
| 3 | Charlie | | 1,2 | NULL |
+----+--------------+------------+-----+---------+
FIND_IN_SET( search_value, comma_separated_list )
searches for the value in the given comma separated string. So, you need to replace the semicolons with commas, which is obviously what REPLACE()
does. The return value of this function is the position where it found the first match, so for example:
SELECT FIND_IN_SET(3, '1,3,5') = 2
SELECT FIND_IN_SET(5, '1,3,5') = 3
SELECT FIND_IN_SET(7, '1,3,5') = NULL