Я должен сказать - я в тупике. Я не могу придумать никакого решения, которое могло бы даже приблизиться. Я бы попытался найти решение в следующих направлениях:
- Определяемые пользователем агрегатные функции. Может быть, вы можете сделать функцию, которая принимает в качестве аргумента желаемое выражение (в упрощенном синтаксисе) и строки для одного человека. Затем функция анализирует выражение и сопоставляет его со строками. Хм ... может быть, 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) (именно в таком порядке!), То я думаю, что он будет таким же быстрым, как и в любом случае.