В MySQL 8.0 вы можете использовать оконные функции для решения этой проблемы.Во-первых, отфильтруйте записи, соответствующие 3 условиям, выполняя подсчет окон и назначая условный ранг, который ставит значение 'http'
на первое место.Затем внешний запрос фильтрует записи, количество окон в которых равно 3 и которые занимают первое место:
SELECT custom_id, value, field_id, cnt
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY custom_id ORDER BY value LIKE '%http%') rn,
COUNT(*) OVER (PARTITION BY custom_id) cnt
FROM mytable t
WHERE
(field_id = '72' AND value = 'No mark')
OR (field_id = '126' AND value like '%http%')
OR (field_id = '122' AND value ='')
) x
WHERE cnt = 3 AND rn = 1
LIMIT 10000
Примечание: на основе данных примера лучше будет написать value LIKE '%http%'
value = 'http'
.
Демонстрация на БД Fiddle :
| custom_id | value | field_id | cnt |
| --------- | ----- | -------- | --- |
| 20987 | http | 126 | 3 |
В более ранних версиях, когда оконные функции недоступны, вы можете выполнить агрегированиев подзапросе для создания списка custom_id
s, которые удовлетворяют условиям, а затем JOIN
результатов с исходной таблицей при фильтрации по записи, которая имеет ожидаемый value
:
SELECT t.*
FROM mytable t
INNER JOIN (
SELECT custom_id
FROM mytable
WHERE
(field_id = '72' AND value = 'No mark')
OR (field_id = '126' AND value like '%http%')
OR (field_id = '122' AND value ='')
GROUP BY custom_id
HAVING count(custom_id)=3
) x ON x.custom_id = t.custom_id
WHERE t.value like '%http%'
Демонстрация на DB Fiddle (те же результаты, что и выше).