Я генерация запроса, который возвращает набор профилей, которые отвечают все условия размещены нижеMySQL заявления для извлечения записи на основе нескольких условий через реляционные таблицы
Я получаю данные, как это в Ruby, затем сделать динамический запрос MySQL на основе содержимого -
[{ attribute_id: 58, parent_profile_name: 'Douglas-Connelly' },
{ attribute_id: 26, parent_profile_name: 'Brekke LLC' },
{ attribute_id: 35, val: 'Asa' },
{ attribute_id: 38, val: 'Stanton' }]
это текущее содержимое базы данных
profile_attribute_values
profile_id attribute_id parent_profile_id val
6 58 2
6 26 5
6 35 nil 'Asa'
6 38 nil 'Stanton'
profile
id name
2 Douglas-Connelly
5 Brekke LLC
6 nil
Мне нужно вернуть все профили которые отвечают всем условиям - профили, которые имеют отношение к profile_attribute_values , где attribute_id является х, а Допустимы у, где attribute_id является х, а имя parent_profile = у
ЧТО Я НАСТОЯЩЕЕ ИМЕЮТ
SELECT * FROM
(SELECT P2. *
FROM profile_attribute_values PAV
INNER JOIN profiles P1 ON P1.id = PAV.parent_profile_id
INNER JOIN profiles P2 ON P2.id = PAV.profile_id
WHERE (PAV.ne_attribute_id = '58' AND P1.`name` = 'Douglas-Connelly')
) A,
(SELECT P1. *
FROM profiles P1
INNER JOIN profile_attribute_values PAV ON P1.id = PAV.profile_id
INNER JOIN profile_attribute_values PAV2 ON P1.id = PAV2.profile_id
WHERE (PAV.ne_attribute_id = '35' AND PAV.val = 'ASA')
AND (PAV2.ne_attribute_id = '38' AND PAV2.val = 'Stanton')
) B
WHERE A.id = B.id
Это вернет
profile
id name
6 nil
это именно то, что я тусклый т, хотя сложная часть является вторым условием parent_profile, где мне нужно attribute_id 26 и parent_profile_name: «Брекки ООО»
Я знаю, что это не будет работать, но мне это нужно сделать что-то вроде этого
SELECT * FROM
(SELECT P2. *
FROM profile_attribute_values PAV
INNER JOIN profiles P1 ON P1.id = PAV.parent_profile_id
INNER JOIN profiles P2 ON P2.id = PAV.profile_id
WHERE (PAV.ne_attribute_id = '58' AND P1.`name` = 'Douglas-Connelly')
AND (PAV.ne_attribute_id = '26' AND P1.`name` = 'Brekke LLC')
) A,
.....
Я генерирую инструкцию SQL динамически, поэтому мне действительно нужно, чтобы она была максимально чистой. Обычно я использую рубиновую активную запись для всего, поэтому я немного приукрашиваю, когда дело доходит до SQL-заявлений. Благодаря!
UPDATE
Хорошо, я нашел отличное решение для создания динамического запроса, что мне нужно, делает один вызов к базе данных. Это готовый класс
class ProfileSearch
def initialize(params, args = {})
@attr_vals = params
@options = args
filter_attrs
end
attr_accessor :parent_attrs, :string_attrs
def search
Profile.joins(generate_query)
end
def generate_query
q = ''
q << parents_query
q << attr_vals_query
end
def parents_query
str = ''
parent_attrs.each_with_index do |pa, i|
str << "INNER JOIN profile_attribute_values PAVP#{i} ON profiles.id = PAVP#{i}.profile_id "\
"AND PAVP#{i}.ne_attribute_id = #{pa} "\
"INNER JOIN profiles PP#{i} ON PP#{i}.id = PAVP#{i}.parent_profile_id "\
"AND PP#{i}.`name` = '#{@attr_vals[pa.to_s]}' "
end
str
end
def attr_vals_query
str = ''
string_attrs.each_with_index do |a, i|
str << "INNER JOIN profile_attribute_values PAVS#{i} ON profiles.id = PAVS#{i}.profile_id "\
"AND PAVS#{i}.ne_attribute_id = #{a} AND PAVS#{i}.val = '#{@attr_vals[a.to_s]}' "
end
str
end
def filter_attrs
ne = NeAttribute.find(@attr_vals.keys)
self.parent_attrs = ne.select{ |x| x.parent_profile)_attr? }.map(&:id)
self.string_attrs = ne.select{ |x| x.string_attr? }.map(&:id)
end
end
Хороший вызов на стыки метод, хотя это по-прежнему создает несколько запросов, и его не получает именно то, что мне нужно , из-за самостоятельного присоединения к отдельному экземпляру таблицы профилей. Мне действительно нужно, чтобы это было максимально оптимизировано, так как его много называли. Я действительно понял, хотя, см. Обновление выше. –