我需要根据他们动态添加的属性(转置表)查询用户
我有 4 张桌子
- 用户- 为用户
- propertyGroup - 对于属性组,可以将组动态添加到数据库
- propertyValue - 用于 propertyGroup 的可能值
- usersPropertyValues - 将用户连接到他的相关属性
它看起来像这样:
users:
------
| id | name | details |
|----|------|---------|
| 1 | Joe | foo |
| 2 | Dan | bar |
propertyGroup:
--------------
| id | name |
|----|----------------|
| 1 | Hobbies |
| 2 | LikeFood |
| 3 | VisitedCountry |
propertyValue:
--------------
| id | propertyGroupId | name |
|----|-----------------|--------------|
| 1 | 1 | Technologies |
| 2 | 1 | Surfing |
| 3 | 2 | Rice |
| 4 | 2 | Meat |
| 5 | 2 | Veg |
| 6 | 3 | USA |
| 7 | 3 | FRANCE |
| 8 | 3 | ISRAEL |
| 9 | 3 | CANADA |
usersPropertyValues:
--------------------
| userId | propertyValueId |
|--------|-----------------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 5 |
| 1 | 6 |
| 1 | 7 |
| 1 | 8 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 2 | 5 |
| 2 | 8 |
| 2 | 9 |
| 2 | 7 |
所以 mix-em-all 查询将如下所示:
select *
from users as u
join usersPropertyValues as upv on upv.userId = u.id
join propertyValues as pv on pv.id = upv.propertyValueId
join propertyGroup as pg on pg.id = pv.propertyGroupId
| id | name | details | userId | propertyValueId | id | propertyGroupId | name | id | name |
|----|------|---------|--------|-----------------|----|-----------------|--------------|----|----------------|
| 1 | Joe | foo | 1 | 1 | 1 | 1 | Technologies | 1 | Hobbies |
| 1 | Joe | foo | 1 | 2 | 2 | 1 | Surfing | 1 | Hobbies |
| 1 | Joe | foo | 1 | 3 | 3 | 2 | Rice | 2 | LikeFood |
| 1 | Joe | foo | 1 | 5 | 5 | 2 | Veg | 2 | LikeFood |
| 1 | Joe | foo | 1 | 6 | 6 | 3 | USA | 3 | VisitedCountry |
| 1 | Joe | foo | 1 | 7 | 7 | 3 | FRANCE | 3 | VisitedCountry |
| 1 | Joe | foo | 1 | 8 | 8 | 3 | ISRAEL | 3 | VisitedCountry |
| 2 | Dan | bar | 2 | 2 | 2 | 1 | Surfing | 1 | Hobbies |
| 2 | Dan | bar | 2 | 3 | 3 | 2 | Rice | 2 | LikeFood |
| 2 | Dan | bar | 2 | 4 | 4 | 2 | Meat | 2 | LikeFood |
| 2 | Dan | bar | 2 | 5 | 5 | 2 | Veg | 2 | LikeFood |
| 2 | Dan | bar | 2 | 8 | 8 | 3 | ISRAEL | 3 | VisitedCountry |
| 2 | Dan | bar | 2 | 9 | 9 | 3 | CANADA | 3 | VisitedCountry |
| 2 | Dan | bar | 2 | 7 | 7 | 3 | FRANCE | 3 | VisitedCountry |
都在这里:http ://sqlfiddle.com/#!3/49329/1
我想通过一组propertyValueId查询数据并获取与该组属性匹配的所有用户,因此用户需要至少具有每个组的属性 - 换句话说,一个 where 原因像这样匹配通用 CNF 子句:(pvId 是 propertyValueId 的缩写)
Property group A Property group B Property group C
(pvId_x or pvId_y) and (pvId_w or pvId_z) and... and (pvId_m or pvId_k)
在上面的例子中,pvId_x&pvId_y 属于 A 组,pvId_w&pvId_z 属于 B 组,以此类推。
我没有工作,我尝试连接 IN 运算符的 AND 运算符(在模拟或部分 - 析取)如图所示(查询上述 sql fiddle):
select distinct u.name, u.id
from users as u
join usersPropertyValues as upv on upv.userId = u.id
join propertyValues as pv on pv.id = upv.propertyValueId
join propertyGroup as pg on pg.id = pv.propertyGroupId
where (pv.propertyGroupId = 1 AND pv.id IN(1,2)) and (pv.propertyGroupId = 2 AND pv.id IN(5,6))
而不是让两个用户(两者都有(1或2)和(5或6)) - 我没有。
我明白为什么结果集是空的,但我不明白如何实现正确的 where 子句。- 怎么做?
我的问题: 如何在上述 SQL 结构中实现 CNF 逻辑?
编辑:例外结果示例:(关于 sqlfiddle 示例:
input --> output
{1,5} --> Joe (user with hobby:tech, likefood:veg)
{2,8} --> Joe,Dan (user with hobby:surfing, VisitedCountry:Israel)
{2,8,9} --> Dan (user with hobby:surfing, VisitedCountry:Israel,Canada)
顺便说一句,我最终需要在 JPA 中实现这一点,所以如果 JPA 中有解决方案,那也很棒。但如果不是 - 我会翻译它......谢谢