【发布时间】:2021-01-23 22:57:02
【问题描述】:
我有以下表格
用户
user_id name
101 Tony
102 Skyle
103 Kenne
兴趣
intrest_id intrest_name
201 Eating
202 Sleeping
203 Drinking
爱好
hobby_id hobby_name
301 Smoking
302 Hiking
303 Browsing
用户兴趣
user_id intrest_id
101 201
102 201
102 202
103 201
103 202
103 203
用户爱好
user_id hobby_id
101 301
102 301
102 302
103 301
103 302
103 303
现在要找对Eating和Sleeping都有兴趣的用户id我写过
select u.user_id
from user u, intrest i, user_intrest ui
where u.user_id = ui.user_id
and i.intrest_id = ui.intrest_id and i.intrest_name in ('Eating', 'Sleeping')
group by u.user_id
having count(i.intrest_name) = 2
输出
user_id
102
103
和上面一样,我也可以找到爱好Smoking,Hiking,Browsing的用户ID如下
select u.user_id
from user u, hobby h, user_hobby uh
where u.user_id = uh.user_id
and h.hobby_id = uh.hobby_id and h.hobby_name in ('Smoking', 'Hiking', 'Browsing')
group by u.user_id
having count(i.intrest_name) = 3
输出
user_id
103
现在我想选择混合这两种方式,如果只传递了兴趣,那么将找到具有这些兴趣的用户,或者如果只传递了爱好,则找到具有这些爱好的用户,或者如果兴趣和爱好都通过了,那么找到具有这些兴趣和爱好的用户
更新: 这是带有本机查询的 spring data rest api 的一部分,其中查询参数是可选的。下面是一个为兴趣寻找用户的工作示例。现在我想将其扩展为包括爱好,因此如果两者都在查找用户的请求中传递,则两者都将被使用
@RestResource(path = "getUserByIntrestsAndHobbies", rel = "getUserByIntrestsAndHobbies")
@Query(value = "SELECT u FROM User u WHERE (COALESCE(:intrests, NULL) IS NOT NULL AND u.userId IN (SELECT u.userId " +
"FROM User u, Intrest i, UserIntrest ui " +
"WHERE u.userId = ui.userId AND i.intrestId = ui.intrestId " +
"AND i.intrestName IN (:intrests) " +
"GROUP BY u.userId " +
"HAVING (:intrestsSize IS NULL OR :intrestsSize = count(i.intrestName))))"
)
Page<User> getUsersByIntrestsAndHobbies(@Param("intrests") List<String> intrests,
@Param("intrestsSize") Long intrestsSize,
@Param("hobbies") List<String> hobbies,
@Param("hobbiesSize") Long hobbiesSize,
Pageable pageable);
【问题讨论】:
-
首先,停止使用隐式(逗号分隔)连接,因为它们已经过时多年了。而是使用显式连接。
-
你说的只传递兴趣是什么意思?
-
这个查询应该只能接受兴趣,如果爱好没有通过@GMB,则给有兴趣的用户
-
对,但是值是如何传递到查询的?
-
但是我们需要查看参数以什么形式到达...您的查询不包含参数 - 如果您要使用参数重新编写它,我们可以为您提供帮助。您已经向我们展示了字面值,但由于那不是现实生活,我们需要更多细节。
标签: sql sql-server join spring-data spring-data-rest