Трябва да кажа - объркан съм. Не мога да измисля някакво решение, което да се доближи. Бих се опитал да потърся решение в следните посоки:
- Дефинирани от потребителя агрегатни функции. Може би можете да създадете функция, която приема като аргумент желания израз (в опростен синтаксис) и редовете за един човек. След това функцията анализира израза и го съпоставя с редовете. Хм... може би MySQL включва някаква конкатенираща агрегатна функция и функция за съвпадение на регулярни изрази? Тогава това може да е решение (макар и вероятно не много бързо).
- Аналитични функции. Не се преструвам, че ги разбирам, но доколкото знам за тях, мисля, че като цяло са в тази посока. Въпреки че не знам дали ще има функция, която да отговаря на тази нужда.
Добавено: Ааа, мисля, че разбрах! Въпреки че мисля, че представянето ще е мизерно. Но това ще работи! Например, ако имате изискване да търсите 1 AND 2 AND (3 OR 4)
тогава ще напишете:
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)
)
Добавено 2: Ето още един, въпреки че производителността вероятно ще бъде още по-лоша:
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: Това е вариант на номер 2, но това всъщност може да има шанс за прилично представяне!
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))
Ако добавите индекс към PersonCriteria на колони (PersonID,CriteriaID) (точно в този ред!), тогава мисля, че това е приблизително толкова бързо, колкото ще получите във всеки случай.