2010-01-07 2 views

Répondre

2

Tout d'abord, en utilisant des valeurs séparées par des virgules dans un champ est problématique, et vous devriez envisager de les stocker dans une table de sepatate à la place. Ensuite, vous pouvez obtenir l'enregistrement plus efficacement:

select ... 
from mainTable t 
inner join valueTable v1 on v1.id = t.id and v1.value = 1 
inner join valueTable v2 on v2.id = t.id and v2.value = 2 
inner join valueTable v3 on v3.id = t.id and v3.value = 3 

Si cela n'est pas possible, vous devez utiliser la méthode de couplage lent. Pour correspondre aux valeurs dans une chaîne séparées par des virgules, vous pouvez utiliser l'opérateur like:

... where 
    concat(',', someField, ',') like '%,1,%' and 
    concat(',', someField, ',') like '%,2,%' and 
    concat(',', someField, ',') like '%,3,%' 

Mettre le séparateur des deux côtés de la valeur recherchée, fait en sorte que vous ne recevez pas de faux positifs. Ajouter les virgules avant et après la valeur du champ permet de trouver la première et la dernière valeur.

+0

Oui Juste ce que je pensais. Avec une table séparée est que je ne peux apparemment pas faire le choix que je veux. SELECT * FROM table WHERE id = '1' ET id = '2' AND id = '3'. La table serait dans ce cas un tableau croisé dynamique: id, user_id, option_id – Cudos

+0

@Cudos: Vous pouvez facilement obtenir le résultat en utilisant une table séparée. Voir l'exemple de requête que j'ai ajouté ci-dessus. – Guffa

+0

@Guffa: Je pensais aussi à quelque chose comme ça: 'SELECT t.name FROM maintable t INNER JOIN valueTable v ON v.valeur IN (1, 2, 3) ET t.id = v.id GROUP BY t.name AYANT COMPTE (*)> = 3' bien que je ne l'ai pas testé. – Powerlord

2

Utiliser l'expression régulière correspondant à la regexes (^|,)1($|,) et (^|,)2($|,) et (^|,)3($|,)

1

Avez-vous considéré ce qu'une recherche optimale pour la valeur 11 ferait dans votre cas?

Comme il n'y a aucun moyen d'affiner la recherche, il est condamné à effectuer une analyse de table pour trouver les valeurs pertinentes.

Vous devriez sérieusement envisager de diviser ces valeurs dans une table distincte, où vous avez une ligne par valeur, toutes liées à la ligne d'origine dans la table d'origine.

Ce serait beaucoup plus correct, beaucoup plus performant, et beaucoup plus facile à traiter.

Cela dit, si vous voulez continuer à utiliser votre approche actuelle, vous pouvez rechercher une valeur en faisant ceci:

WHERE ','+ column + ',' LIKE '%,' + value + ',%' 

Cela recherche ',11,22,33,' pour '%,11,%', notez les virgules à chaque extrémité des deux la colonne et la valeur, cela vous assurera que vous n'obtenez pas de faux positifs en raison de correspondances partielles.

+0

De commentaire ci-dessous: Avec une table séparée est que je ne peux apparemment pas faire le choix que je veux. SELECT * FROM table WHERE id = '1' ET id = '2' AND id = '3'. La table serait dans ce cas un tableau croisé dynamique: id, user_id, option_id.Comment feriez-vous face à cela? – Cudos

+0

En supposant que vous divisez le champ en un tableau séparé, vous voulez dire que vous voulez que les utilisateurs pour lesquels les options 1, 2 et 3 sont tous présents, est-ce? –

+0

Oui. Vous avez raison - à la fois dans votre hypothèse et dans le code ci-dessus. Mais comme vous et au-dessus de l'affiche a souligné faire une table séparée devrait être fait. Après avoir vu son SELECT je suis allé avec la solution recommandée. – Cudos

Questions connexes