Question

I want to do a query containing 'like' and 'not like'.

Current example: i want everything starting with '1|%' but not with '1|6|199|%' or '1|6|200|%'.

Current query:

'SELECT * FROM `links` WHERE `category` LIKE '1|%' NOT LIKE '1|6|199|%','1|6|200|%' ORDER BY `score` DESC LIMIT 9'.

But that doesn't work. Any tips? thx

Was it helpful?

Solution

Just add "and category"...

SELECT * FROM links 
WHERE category LIKE '1|%' 
  AND category NOT LIKE '1|6|199|%','1|6|200|%' 
ORDER BY score DESC LIMIT 9

Actually, the comma separated condition is not a syntax I'm familiar with. If that's not working, try this instead:

SELECT * FROM links 
WHERE category LIKE '1|%' 
  AND category NOT LIKE '1|6|199|%'
  AND category NOT LIKE '1|6|200|%' 
ORDER BY score DESC LIMIT 9

OTHER TIPS

You can use regexps:

SELECT  *
FROM    links 
WHERE   category LIKE '1|%' 
        AND category NOT REGEXP '^1\\|6\\|(199|200)\\|'
ORDER BY
        score DESC
LIMIT 9

Note that REGEXP's don't use indexes, while LIKE does.

In this query, LIKE '1|%' will serve as a coarse filter using the index on category if any, while REGEXP's will fine filter the results.

I think a bigger problem is that you have de-normalized tables. The correct answer would be to normalize your tables.

But if you can't do that, you should use commas as separators and FIND_IN_SET() instead:

WHERE FIND_IN_SET('1', category) > 1
  AND FIND_IN_SET('6', category) > 1
  AND FIND_IN_SET('199', category) = 0
  AND FIND_IN_SET('200', category) = 0

It is also possible to use two inner join, probably not the best solution for this query, but could still be useful.

SELECT * FROM links

INNER JOIN (SELECT * FROM links WHERE category NOT LIKE '1|6|199|%') AS escl1 ON (links.category=escl1.category)

INNER JOIN (SELECT * FROM links WHERE category NOT LIKE '1|6|200|%') AS escl2 ON (links.category=escl2.category)

WHERE category LIKE '1|%'

ORDER BY score DESC LIMIT 9

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top