无法找到在此类伪搜索索引表上为条件添加顺序的方法:
----------------------------------
| id | person_id | field | value |
----------------------------------
| 1 | 1 | fname | John |
| 2 | 1 | lname | Smith|
| 3 | 1 | zip | 3000 |
| 4 | 2 | fname | John |
| 5 | 2 | lname | Doe |
| 6 | 2 | zip | 3000 |
----------------------------------
search_index表是人员实体的索引,可以包含任意数量的任何类型的属性(当然,这是现实生活中的一个简单例子)。一个人#34;可以有fname设置,另一个可能没有等等。然后,客户端应用程序发送通用搜索请求,f.i。 ((fname = John OR fname = Karl)AND lname = Smith and zip = 3000) - 这种东西。所以系统是相当通用的 - search_index中的可搜索字段列表和任何类型的布尔搜索查询。 orderby也是如此 - 可以是任何可搜索的字段。
在SQL中我会做类似的事情:
SELECT si1.person_id from search_index si1
LEFT OUTER JOIN search_index si2 ON si1.id = si2.id
WHERE si2.field='lname'
AND si1.person_id in (select person_id from search_index where field = 'zip' and answer = '3000')
ORDER BY si2.value
按" lname"订购找到的结果。
可能使用HQL,但搜索标准是从搜索字符串动态构建的,与动态HQL构建相比,Hibernate Criteria API使其更容易。
答案 0 :(得分:1)
为什么LEFT JOIN在同一个表中,然后在WHERE子句中使用JOINED表?这相当于INNER JOIN。
为什么在加入这两个表时还有一个额外的子选择。
为什么你甚至按照他们的ID加入两张桌子呢?在您的此查询中,您加入相同的行(因为您使用表ID作为连接条件)。
这个查询可以成为您想要的吗?
SELECT si1.person_id
from search_index si1
LEFT OUTER JOIN search_index si2 ON si1.person_id = si2.person_id AND si2.field='lname'
WHERE si1.field = 'zip' and si1.answer = '3000'
ORDER BY si2.value
HQL和Criteria查询只能在导航现有关联时帮助您(自连接不是这种情况)。所以在这种情况下你应该使用原生查询。
现在,回到您的查询。您可以删除JOIN并将其写为:
SELECT si1.person_id
from search_index si1
WHERE si1.field='lname'
AND si1.person_id in (select person_id from search_index where field = 'zip' and answer = '3000')
ORDER BY si1.value
在这种情况下,您可以编写HQL查询:
select p.id
from SearchIndex si
join si.person p
where
si.field = :field1 and
p.id in (select si2.person.id from SearchIndex si2 where si2.field = : field2 and answer = :answer)
order by si.value
如果' lname'字段仅对订购有用,然后您需要将子查询移动到主查询中并移动' lname'在连接中:
SELECT si1.person_id
from search_index si1
where si1.field = 'zip' and si1.answer = '3000'
LEFT OUTER JOIN search_index si2 ON si1.person_id = si2.person_id AND si2.field='lname'
ORDER BY si2.value
由于自连接语法,这需要本机查询。