2011-01-31 8 views
2

Je suis en train de subir un blocage du cerveau avec ce que je pensais être une simple requête.Requête MySQL pour extraire un identifiant distinct avec plusieurs zones

J'ai une table comme ce qui suit:

ID DETAILID NAME  
------------------------------------------------- 
1 1   Sed ut perspiciatis unde 
2 1   omnis iste natus error 
3 1   sit voluptatem accusantium 
4 1   doloremque laudantium 
5 2   totam rem aperiam 
6 2   labore et dolore 
7 3   voluptate velit esse 
8 3   occaecati cupiditate non 
9 3   culpa qui officia 
10 3   placeat facere possimus 
11 3   Nam libero tempore 

Je veux rechercher le champ NOM plusieurs fois avec « %% » LIKE (nombre de LIKE ce sera au hasard), mais je veux seulement revenir un distinct DETAILID où les LIKE sont tous trouvés dans les enregistrements où le DETAILID est le même. Je tourne en rond et je n'arrive nulle part rapidement. Quelqu'un peut-il aider?

Répondre

1

Cette requête vous donne les DETAILIDs qui correspondent à toutes les conditions COMME

SELECT DETAILID 
FROM 
(
    select DETAILID, 1 as WhichMatch 
    from tbl 
    where NAME LIKE '%a%' 
    UNION ALL 
    select DETAILID, 2 as WhichMatch 
    from tbl 
    where NAME LIKE '%b%' 
    UNION ALL 
    select DETAILID, 3 as WhichMatch 
    from tbl 
    where NAME LIKE '%c%' 
) SQ 
GROUP BY DETAILID 
HAVING COUNT(DISTINCT WhichMatch) = 3 
+0

Cela donne le detailid distinct mais le detailid est retourné même si tous les LIKE ne sont pas vrai pour le detailid particulier. J'ai besoin du detailid renvoyé seulement si tous les LIKE sont vrais pour tous les noms qui ont le detailid particulier. J'espère que cela a du sens. Merci. – scampbell

+0

@scampbell - Réponse éditée après avoir réinterprété votre question – RichardTheKiwi

+0

Excellent, ça a fait l'affaire! Merci beaucoup. Une chance d'explication de la requête? Je réalise qu'une table temporaire est créée mais je ne sais pas comment toutes les valeurs de WhichMatch sont calculées. Merci encore.Id voter votre réponse, mais ne pas avoir suffisamment de rep pour le moment. – scampbell

-1

ne serait-ce de travail?

SELECT DISTINCT DETAILID 
FROM MyTable 
WHERE NAME LIKE '%something%' 
    or NAME LIKE '%sometingelse%
+0

Cela donne le DETAILID distinct mais le DETAILID est renvoyé même si tous les LIKE ne sont pas vrai pour le DETAILID particulier. J'ai besoin du DETAILID retourné seulement si tous les LIKE sont vrais pour tous les NOMs ayant le DETAILID particulier. J'espère que cela a du sens. Merci. – scampbell

-1

Eh bien, après avoir lu vos commentaires sur deux autres réponses, je crois que vous avez besoin de ce -

utilisation ET au lieu de OU dans la requête -

SELECT DISTINCT DETAILID 
FROM MyTable 
WHERE NAME LIKE '%something%' 
    AND NAME LIKE '%someting1%' 
    AND NAME LIKE '%someting2%' 
+0

Dans ce cas, il ne retournera le DETAILID que lorsque le nom d'un enregistrement unique contient tous les LIKE. Je veux qu'il retourne le DETAILID quand tous les enregistrements avec le même DETAILID contiennent tous les LIKE quelque part dans cet ensemble d'enregistrements. Merci. – scampbell

-1

Je pense la solution la plus simple consiste à le faire dans plusieurs requêtes. Sélection du count() de l'identifiant distinct avec un WHERE et sélection du count() de l'identifiant distinct sans condition where. Comparer ces 2 serait une façon parfaite de déterminer si tous les 'noms' de 'detialids' correspondent à vos LIKE

0

Parce que vous cherchez toutes les valeurs "LIKE", vous aurez besoin d'un OU entre eux, un cOUNT (*) pour voir combien de match et GROUP BY par ID, et AYANT pour correspondre au nombre que vous attendez ...

select 
     DETAILID, 
     count(*) RecsFound 
    from 
     YourTable 
    where 
      NAME LIKE '%a%' 
     or NAME LIKE '%b%' 
     or NAME LIKE '%c%' 
     or NAME LIKE '%d%' 
    group by 
     DetailID 
    having 
     RecsFound = 4 

comme vous l'avez mentionné, il pourrait être un nombre aléatoire de « comme "Qualificateurs et sons comme il sera une requête SQL construite dynamiquement. Par conséquent, assurez-vous que le nombre de clauses HAVING correspond aux entrées que vous testez.

EDIT - révisée réponse IF mouvement() à l'endroit où la section

select 
     DETAILID 
    from 
     YourTable 
    where 
      if(NAME LIKE '%a%', 1, 0) 
     + if(NAME LIKE '%b%', 1, 0) 
     + if(NAME LIKE '%c%', 1, 0) 
     + if(NAME LIKE '%d%', 1, 0) = 4 

Je suppose que je le regardais d'une table à plusieurs rangées où chaque entrée était son propre élément que vous testez. Vous cherchez à avoir toutes les valeurs dans la même ROW correspondant à tous les LIKEs ... Bien que vous avez accepté une autre réponse, voici une autre alternative SANS utiliser toutes les unions distinctes ...

De plus, passe par la table UNE FOIS au lieu de 2, 3, 4 ou plus via toutes les unions, puis avoir un groupe de ... Il frappe le record une FOIS, qualifie les 4 conditions et est FAIT.

+0

Merci beaucoup. C'est une requête SQL construite dynamiquement oui. Votre exemple est génial et aurait fonctionné indépendamment du fait que certains de mes noms sont très similaires, donc un semblable peut trouver plus d'un enregistrement augmentant ainsi le nombre mais pas tous les goûts auraient été trouvés. J'espère que cela a du sens. – scampbell

+0

@ scampbell, pour votre commentaire, voici une requête révisée qui n'a pas besoin de syndicats complexes et devrait TOUJOURS obtenir la réponse que vous cherchiez. – DRapp

+0

Merci, mais je ne peux pas obtenir ce travail. J'obtiens l'erreur: # 1054 - Colonne inconnue 'LikeMatches' dans 'where clause'. Si je prends le cas échéant et que je lance la requête, je peux commander par LikeMatches, ce qui me semble très étrange. Mais même quand je fais cet ordre par 3 matchs (dont le code accepté trouve 4 correspondances de) LikeMatches ne vaut que 2 pour 2 detailid identiques. Je sais que je pourrais utiliser un résultat distinct mais même si seulement 1 aurait 2 LikeMatches et aucun n'aurait les 3 requis. – scampbell

Questions connexes