Если у вас `usr-ex4-ids` — это строка, в которой через запятую перечислены идентификаторы, то неработающий запрос, после выполнения подзапроса, выглядит так:
# . . .
AND `ex4-id` NOT IN ("17,18,19,20")
То есть, как вы видите, в скобках получается не несколько элементов, разделённых запятыми, а один элемент — строка, внутри которой есть цифры и запятые.
Есть несколько вариантов.
1. Можно сделать дополнительную таблицу, в которую записывается соответствие ex4-id и user-id.
CREATE TABLE `usr-ex4-ids` (
`ex4-id` int(11) NOT NULL,
`usr-id` int(11) NOT NULL,
PRIMARY KEY (`ex4-id`,`usr-id`)
)
Далее эта таблица заполняется соответствующими значениями (один ex4-id на строку, а не перечисление ex4-id в одной строке через запятую). Итоговый запрос, который сейчас у вас не работает, будет выглядеть так:
# . . .
AND `ex4-id` NOT IN (SELECT `ex4-id` FROM `usr-ex4-ids` WHERE `usr-id` = 51)
2. Можно попытаться сделать конвертацию строки в массив. Встроенных функций в MySQL для таких задач нет. Советую посмотреть комментарии пользователей к
списку строковых функций MySQL — там есть несколько интересных решений (комментарии, как и положено комментариям, находятся в конце страницы).
Но вообще, я советую первый вариант, так как он логичнее, проще и быстрее. По второму варианту вам скорее всего придётся собственные функции MySQL писать. И они будут работать гораздо медленнее, чем вариант с нормализацией БД.