Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Erweiterte (?) UND/ODER-Abfrage

Ich muss sagen - ich bin ratlos. Mir fällt keine Lösung ein, die auch nur annähernd käme. Ich würde versuchen, in diesen Richtungen nach einer Lösung zu suchen:

  • Benutzerdefinierte Aggregatfunktionen. Vielleicht können Sie eine Funktion erstellen, die als Argument den gewünschten Ausdruck (in vereinfachter Syntax) und die Zeilen für eine einzelne Person verwendet. Die Funktion analysiert dann den Ausdruck und gleicht ihn mit den Zeilen ab. Hmm ... vielleicht enthält MySQL eine verkettende Aggregatfunktion und eine Regex-Matching-Funktion? Das könnte dann eine Lösung sein (wenn auch wahrscheinlich keine sehr schnelle).
  • Analysefunktionen. Ich behaupte nicht, dass ich sie verstehe, aber so viel ich über sie weiß, denke ich, dass sie im Allgemeinen in diese Richtung gehen. Obwohl ich nicht weiß, ob es eine Funktion geben wird, die diesem Bedarf gerecht wird.

Hinzugefügt: Ahh, ich glaube, ich habe es verstanden! Obwohl ich denke, dass die Leistung miserabel sein wird. Aber das wird funktionieren! Zum Beispiel, wenn Sie nach 1 AND 2 AND (3 OR 4) suchen müssen dann würdest du schreiben:

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)
    )

Hinzugefügt 2: Hier ist eine andere, obwohl die Leistung wahrscheinlich noch schlechter sein wird:

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

3 hinzugefügt: Dies ist eine Variation von Nr. 2, aber das könnte tatsächlich eine Chance auf eine anständige Leistung haben!

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))

Wenn Sie PersonCriteria auf Spalten (PersonID,CriteriaID) einen Index hinzufügen (genau in dieser Reihenfolge!), dann denke ich, dass es ungefähr so ​​​​schnell ist, wie Sie es auf jeden Fall bekommen werden.