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.