Mysql
 sql >> Database >  >> RDS >> Mysql

Query avanzata (?) AND/OR

Devo dire che sono perplesso. Non riesco a pensare a nessuna soluzione che si avvicini nemmeno lontanamente. Proverei a cercare una soluzione in queste direzioni:

  • Funzioni aggregate definite dall'utente. Forse puoi creare una funzione che prenda come argomento l'espressione desiderata (in una sintassi semplificata) e le righe per una singola persona. La funzione analizza quindi l'espressione e la confronta con le righe. Hmm ... forse MySQL include alcune funzioni di aggregazione concatenate e una funzione di corrispondenza delle espressioni regolari? Questa potrebbe essere una soluzione allora (anche se probabilmente non molto veloce).
  • Funzioni analitiche. Non pretendo di capirli, ma per quanto ne so io, penso che generalmente siano in questa direzione. Anche se non so se ci sarà una funzione adatta a questa esigenza.

Aggiunto: Ah, credo di aver capito! Anche se penso che la performance sarà miserabile. Ma questo funzionerà! Ad esempio, se hai il requisito per cercare 1 AND 2 AND (3 OR 4) quindi dovresti scrivere:

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

Aggiunto 2: Eccone un altro, anche se le prestazioni saranno probabilmente anche peggiori:

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

Aggiunto 3: Questa è una variazione del numero 2, ma potrebbe effettivamente avere la possibilità di ottenere prestazioni decenti!

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

Se aggiungi un indice a PersonCriteria sulle colonne (PersonID,CriteriaID) (esattamente in questo ordine!), penso che in ogni caso sia più veloce che otterrai.