One option uses a derived table to list the words, then aggregation:
select b.id, b.title, count(*) no_matches
from books b
inner join (
select 'word1' word
union all select 'word2'
union all select 'word3'
) w on b.title like concat('%', w.word, '%')
group by b.id, b.title
order by no_matches desc
In very recent versions of MySQL, you can use the VALUES()
row-constructor to enumerate the words, which shortens the query:
select b.id, b.title, count(*) no_matches
from books b
inner join (values(row('word1'), row('word2'), row('word3')) b(word)
on b.title like concat('%', w.word, '%')
group by b.id, b.title
order by no_matches desc
This assumes that the "words" are just that - words. If they contain regular expression patterns, they you need to use a regex match instead of like
:
on b.title regexp w.word