首页 > 解决方案 > 选择另一个联接表中的行匹配条件的所有行

问题描述

所以我想选择另一个表中的行子集与给定值匹配的所有行。我有以下表格:

Main Profile:
+----+--------+---------------+---------+
| id |  name  | subprofile_id | version |
+----+--------+---------------+---------+
|  1 | Main 1 |             4 |       1 |
|  2 | Main 1 |             5 |       2 |
|  3 | Main 2 |           ... |       1 |
+----+--------+---------------+---------+

Sub Profile:
+---------------+----------+
| subprofile_id | block_id |
+---------------+----------+
|             4 |        6 |
|             4 |        7 |
|             5 |        8 |
|             5 |        9 |
+---------------+----------+

Block:
+----------+-------------+
| block_id | property_id |
+----------+-------------+
|        7 |          10 |
|        7 |          11 |
|        7 |          12 |
|        7 |          13 |
|        8 |          14 |
|        8 |          15 |
|        8 |          16 |
|        8 |          17 |
|      ... |         ... |
+----------+-------------+

Property:
+----+--------------------+--------------------------+
| id |        name        |          value           |
+----+--------------------+--------------------------+
| 10 | Description        | XY                       |
| 11 | Responsible person | Mr. Smith                |
| 12 | ...                | ...                      |
| 13 | ...                | ...                      |
| 14 | Description        | XY                       |
| 15 | Responsible person | Mrs. Brown               |
| 16 | ...                | ...                      |
| 17 | ...                | ...                      |
+----+--------------------+--------------------------+

用户可以在属性表上定义多个条件。例如:

我需要所有具有所有匹配属性的最高版本的“主要配置文件”,当然可以有更多不匹配的。它在 JPA 中应该是可行的,因为我会将其转换为 QueryDSL 以使用用户输入构建类型安全的动态查询。

我已经搜索了有关类似问题的所有问题,但无法将答案投射到我的问题上。此外,我已经尝试编写一个运行良好但检索到至少具有一个匹配条件的所有行的查询。因此我需要我的集合中的所有属性,但它只获取(获取连接,我的代码示例中缺少)匹配的属性。

from MainProfile as mainProfile
  left join mainProfile.subProfile as subProfile
  left join subProfile.blocks as block
  left join block.properties as property
where mainProfile.version = (select max(mainProfile2.version)from MainProfile as mainProfile2 where mainProfile2.name = mainProfile.name) and ((property.name = 'Description' and property.value = 'XY') or (property.name = 'Responsible person' and property.value = 'Mr. Smith'))

运行我的查询我得到了两行:

  1. 主要 1 与版本 2
  2. 主 2 与版本 1

由于“主要 2”中“负责人”的不匹配,我原本预计只会得到一排


编辑1:

所以我找到了一个可行但可以改进的解决方案:

select distinct mainProfile
from MainProfile as mainProfile 
  left join mainProfile.subProfile as subProfile
  left join subProfile.blocks as block
  left join block.properties as property
where mainProfile.version = (select max(mainProfile2.version)from MainProfile mainProfile2 where mainProfile2.name = mainProfile.name)
and ((property.name = 'Description' and property.content = 'XY') or (property.name = 'Responsible person' and property.content = 'Mr. Smith'))
group by mainProfile.id
having count (distinct property) = 2

它实际上检索了正确的“主要配置文件”。但问题是,只有两个找到的属性被获取。由于进一步处理,我需要所有属性。

标签: sqlpostgresqljpajpqlquerydsl

解决方案


推荐阅读