Я генерирую запросы, которые выполняют поиск по тегам в следующих таблицах:
entry : id, name, desc
tag : id, name
entry_tag : entry, tag, val
Запрос генерируется из введенного пользователем предиката, например:
(year >= 1990 and year < 2000) and (status = 'complete' or status = 'pending')
Это похоже на следующее:
select * from entry where id in
(select entry
from
(select t0.entry, t0.val as <strong>c0</strong>, t1.val as <strong>c1</strong>, …<strong>[1]</strong>
from
(select entry, val from entry_tag where tag in
(select id from tag where name = 'year')) as <strong>t0</strong>,
(select entry, val from entry_tag where tag in
(select id from tag where name = 'status')) as <strong>t1</strong>,
…<strong>[2]</strong>
where t0.entry = t1.entry and …<strong>[3]</strong>) as t
where
…<strong>[4]</strong>);
(Глубокое вложение - моя наивная попытка свести к минимуму количество поездок туда и обратно, если, конечно, предположить, что это хорошая вещь ™).
Поиск тегов по name
и псевдонимов каждый value
до c0
… cn
в порядке появления ввода.
Псевдоним каждый tag_entry
запрос к соответствующему t0
… tn
.
Отображение групповых тегов по entry
.
Вставьте преобразованное логическое выражение непосредственно в предложение where
, например ::
.
(cast(c0 as signed) >= 1990 and cast(c0 as signed) < 2000)
and (c1 = 'complete' or c1 = 'pending')
Есть ли лучший способ сделать это, или я на правильном пути?
Кажется неправильным производить это:
t0.entry = t1.entry and … and t0.entry = tn.entry
Я просто не уверен, как еще поступить так, чтобы сохранить структуру предиката, введенного пользователем. Я не хочу создавать искаженную серию соединений, когда я могу выполнить прямое механическое преобразование.