web-dev-qa-db-fra.com

comme et non comme dans une requête mysql

Je souhaite effectuer une requête contenant 'like' et 'not like'.

Exemple actuel: je veux tout ce qui commence par '1 |%' mais pas par '1 | 6 | 199 |%' ou '1 | 6 | 200 |%'.

Requête en cours: 

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

Mais ça ne marche pas. Des conseils? THX

18
Maurice Kroon

Ajoutez simplement "et la catégorie" ...

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

En fait, la condition séparée par des virgules n'est pas une syntaxe que je connais bien. Si cela ne fonctionne pas, essayez plutôt ceci:

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
30
Michael Haren

Vous pouvez utiliser regexps:

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

Notez que REGEXP n'utilise pas d'index, alors que LIKE l'utilise.

Dans cette requête, LIKE '1|%' servira de filtre grossier à l'aide de l'index sur category, le cas échéant, tandis que REGEXP filtrera les résultats.

3
Quassnoi

Je pense qu'un problème plus important est que vous avez des tables dé-normalisées. La bonne réponse serait de normaliser vos tables.

Mais si vous ne pouvez pas faire cela, vous devriez utiliser des virgules comme séparateurs et FIND_IN_SET() à la place:

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
2
longneck

Il est également possible d’utiliser deux jointures internes, ce qui n’est probablement pas la meilleure solution pour cette requête, mais qui pourrait tout de même être utile.

SELECT * FROM liens

INNER JOIN (SELECT * FROM liens WHERE catégorie pas comme '1 | 6 | 199 |%') AS escl1 ON (links.category = escl1.category)

INNER JOIN (SELECT * FROM liens WHERE catégorie pas comme '1 | 6 | 200 |%') AS escl2 ON (links.category = escl2.category)

O la catégorie aime '1 |%'

ORDER BY score DESC LIMIT 9

0
Ash