Если нет веской причины для того, чтобы идентификатор категории был представлен только частью строки в таблице списков, лучший способ обработать такую структуру данных - это добавить столбец category_id в LISTINGS.table , и убедитесь, что при добавлении или редактировании списка этот столбец заполнен правильно.
Это позволит просто JOIN
две таблицы ON categories.id = listings.category_id
и имеет гораздо больший смысл.Это также значительно повысило бы производительность.
Если вы хотите сохранить структуру БД как есть, вы можете использовать временную таблицу с LIKE и CONCAT:
DROP TABLE IF EXISTS temp;
CREATE TABLE temp AS
SELECT categories.id, COUNT(*) AS c
FROM categories
JOIN listings ON listings.category LIKE CONCAT('%',categories.id,'%')
GROUP BY categories.id;
UPDATE categories, temp
SET categories.num_listings = temp.c
WHERE categories.id = temp.id;