Muszę powiedzieć - jestem zakłopotany. Nie potrafię wymyślić żadnego rozwiązania, które byłoby nawet bliskie. Spróbowałbym poszukać rozwiązania w tych kierunkach:
- Funkcje agregujące zdefiniowane przez użytkownika. Może możesz stworzyć funkcję, która jako argument przyjmuje żądane wyrażenie (w uproszczonej składni) i wiersze dla jednej osoby. Następnie funkcja analizuje wyrażenie i dopasowuje je do wierszy. Hmm... może MySQL zawiera jakąś konkatenującą funkcję agregującą i funkcję dopasowującą regex? To może być rozwiązanie (choć prawdopodobnie niezbyt szybkie).
- Funkcje analityczne. Nie udaję, że je rozumiem, ale o ile wiem o nich, to myślę, że generalnie zmierzają w tym kierunku. Chociaż nie wiem, czy będzie funkcja, która zaspokoi tę potrzebę.
Dodano: Ach, myślę, że to rozumiem! Chociaż myślę, że występ będzie marny. Ale to zadziała! Na przykład, jeśli musisz wyszukać 1 AND 2 AND (3 OR 4)
wtedy napisałbyś:
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)
)
Dodano 2: Oto kolejny, choć wydajność prawdopodobnie będzie jeszcze gorsza:
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
Dodano 3: Jest to odmiana nr 2, ale w rzeczywistości może mieć szansę na przyzwoitą wydajność!
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))
Jeśli dodasz indeks do PersonCriteria w kolumnach (PersonID,CriteriaID) (dokładnie w tej kolejności!), to myślę, że jest to mniej więcej tak szybko, jak to możliwe.