sql >> Databáze >  >> RDS >> Mysql

Rozšířený (?) AND / OR dotaz

Musím říct - jsem v šoku. Nedokážu si představit žádné řešení, které by se jen blížilo. Zkusil bych hledat řešení v těchto směrech:

  • Uživatelem definované agregační funkce. Možná můžete vytvořit funkci, která vezme jako argument požadovaný výraz (ve zjednodušené syntaxi) a řádky pro jednu osobu. Funkce pak analyzuje výraz a porovná jej s řádky. Hmm... možná MySQL obsahuje nějakou zřetězenou agregační funkci a funkci porovnávání regulárních výrazů? Pak by to mohlo být řešení (i když pravděpodobně ne příliš rychlé).
  • Analytické funkce. Nepředstírám, že jim rozumím, ale pokud o nich vím, myslím, že jsou obecně tímto směrem. I když nevím, jestli se najde funkce, která by této potřebě vyhovovala.

Přidáno: Aha, myslím, že to chápu! I když si myslím, že výkon bude mizerný. Ale tohle bude fungovat! Máte-li například požadavek na vyhledávání 1 AND 2 AND (3 OR 4) pak byste napsali:

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

Přidáno 2: Zde je další, i když výkon bude pravděpodobně ještě horší:

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

Přidáno 3: Toto je variace č. 2, ale ve skutečnosti by mohla mít šanci na slušný výkon!

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

Pokud přidáte index do PersonCriteria do sloupců (PersonID,CriteriaID) (přesně v tomto pořadí!), pak si myslím, že je to v každém případě asi tak rychlé, jak se dostanete.



  1. Jak načíst pole z výsledku dotazu MySQL v bash

  2. Aktualizovat více řádků jedním dotazem?

  3. Jak obnovit Galera Cluster nebo replikaci MySQL ze syndromu rozděleného mozku

  4. Vypořádání se s časy a po půlnoci