我正在生成在下表中执行标记搜索的查询:
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 c0, t1.val as c1, …[1]
from
(select entry, val from entry_tag where tag in
(select id from tag where name = 'year')) as t0,
(select entry, val from entry_tag where tag in
(select id from tag where name = 'status')) as t1,
…[2]
where t0.entry = t1.entry and …[3]) as t
where
…[4]);
(深度嵌套是我天真的尝试,以尽量减少往返次数,当然假设这是一件好事。)
按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
我只是不确定如何以保留用户输入的谓词结构的方式来解决这个问题。当我可以进行直接的机械转换时,我不想生成一系列错误的连接。