Mysql
 sql >> Base de données >  >> RDS >> Mysql

Requête AND / OR avancée (?)

Je dois dire - je suis perplexe. Je ne peux penser à aucune solution qui viendrait même près. J'essaierais de chercher une solution dans ces directions :

  • Fonctions d'agrégation définies par l'utilisateur. Peut-être pouvez-vous créer une fonction qui prend comme argument l'expression souhaitée (dans une syntaxe simplifiée) et les lignes pour une seule personne. La fonction analyse ensuite l'expression et la compare aux lignes. Hmm ... peut-être que MySQL inclut une fonction d'agrégation de concaténation et une fonction de correspondance de regex? Cela pourrait être une solution alors (bien que probablement pas très rapide).
  • Fonctions analytiques. Je ne prétends pas les comprendre, mais pour autant que j'en sache, je pense qu'ils vont généralement dans cette direction. Bien que je ne sache pas s'il y aura une fonction qui répondra à ce besoin.

Ajouté : Ahh, je crois que j'ai compris ! Bien que je pense que la performance sera misérable. Mais cela fonctionnera ! Par exemple, si vous devez rechercher 1 AND 2 AND (3 OR 4) alors vous écririez :

SELECT
    *
FROM
    Persons A
WHERE
    EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=1)
    AND
    EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=2)
    AND
    (
        EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=3)
        OR
        EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=4)
    )

Ajouté 2 : En voici un autre, même si les performances seront probablement encore pires :

SELECT p.* FROM Person p
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID=1) c1 ON p.PersonID=c1.PersonID
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID=2) c2 ON p.PersonID=c2.PersonID
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID IN (3,4)) c3 ON p.PersonID=c3.PersonID

Ajouté 3 : Il s'agit d'une variante du n° 2, mais cela pourrait en fait avoir une chance d'obtenir une performance décente !

SELECT p.* FROM
    Person p
    JOIN PersonCriteria c1 on (p.PersonID=c1.PersonID AND c1.CriteriaID=1)
    JOIN PersonCriteria c2 on (p.PersonID=c2.PersonID AND c2.CriteriaID=2)
    JOIN PersonCriteria c3 on (p.PersonID=c3.PersonID AND c3.CriteriaID IN (3,4))

Si vous ajoutez un index à PersonCriteria sur les colonnes (PersonID,CriteriaID) (exactement dans cet ordre !), alors je pense que c'est à peu près aussi rapide que vous le ferez dans tous les cas.