Мне нужно создать графический интерфейс, с помощью которого пользователи могут выбрать несколько атрибутов, которые будут использоваться для запроса базы данных для поиска подходящих лиц. Я ищу идеи, как динамически генерировать запрос базы данных по выбору пользователя.
Запрос будет содержать несколько полей, но для получения этой идеи я приведу только три из приведенных ниже:
Род занятий – может быть от 0 до n строк занятия. Если указаны строки занятости, один из них должен соответствовать.
Возраст может быть задан как:
В запросе параметр возраста необязателен. Кроме того, пользователь может указать, является ли возраст требуемым параметром. Если это не требуется, и у человека нет возраста, это его профиль, возрастные критерии игнорируются для этого человека.
Примеры запросов:
Никаких критериев не было дано:
select * from persons
Было дано только занятие:
select * from persons where occupation = 'dentist'
Было дано несколько занятий:
select * from persons where (occupation = 'dentist' or occupation = 'engineer')
Возраст дается как больше, чем стоимость, и он должен существовать в профиле человека:
select * from persons where age >= 30
Высота была задана как диапазон, и ее не обязательно присутствовать в профиле человека:
select * from persons where (height is null or (height >= 30 and height <= 40))
Сочетание различных критериев:
select * from persons where occupation = 'dentist' and age >= 30 and (height is null or (height >= 30 and height <= 40))
Я уже реализовал код, который способен генерировать запросы как строки, но это, конечно, не слишком красиво. Я ищу идеи, которые были бы самым эффективным и красивым способом достижения этого.
Попробуйте что-то вроде Zend_Db_Select
. Он обеспечивает (свободный) интерфейс для генерации запросов и обработки синтаксиса для вас, например
$select = $db->select(); $select->from( /* ...specify table and columns... */ ) ->where( /* ...specify search criteria... */ ) ->where( /* ...specify other criteria... */ ) ->order( /* ...specify sorting criteria... */ );
У меня было аналогичное требование в одном из моих недавних проектов, где у пользователей есть файл конфигурации, содержащий критерии фильтра, которые автоматически применяются к определенным таблицам в базе данных, что ограничивает то, что пользователям разрешено видеть, например, ограничивать продукты фиксированным клиентом, но все же разрешать динамическая фильтрация через графический интерфейс пользователя, например, для категории продукта.
Я решил это, предложив моей модели базовый запрос, а затем выполнив этот базовый запрос через декоратор, который будет применять все критерии, которые пользователь имеет в своей конфигурации, например, ( faux-код ).
request = Request->getParams() // selection criteria set from GUI sql = Products->getBaseQuery(request) // basic query for requested View sql = Decorator->applyUserConfig(sql) // custom fixed user filter results = sql->execute()
Это не будет напрямую отвечать на ваш вопрос, но вот небольшой совет для вас, вместо того, чтобы писать свой запрос следующим образом:
select * from persons where (occupation = 'dentist' or occupation = 'engineer')
Попробуй это:
select * from persons where occupation IN ('dentist','engineer')
Это легче читать и легко создавать сценарий PHP.
Похоже, что у вас есть конечное количество запросов, которые могут быть сгенерированы, поэтому я предлагаю записать их все с параметрами, а затем с помощью логики выбора выработать для вызова и настройки значений параметров.