Выберите все строки, где строки в другой объединенной таблице соответствуют условию - PullRequest
0 голосов
/ 08 июля 2019

Поэтому я хочу выбрать все строки, где подмножество строк в другой таблице соответствуют заданным значениям. У меня есть следующие таблицы:

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 | ...                | ...                      |
+----+--------------------+--------------------------+

Пользователь может определить несколько условий в таблице свойств. Например:

  • Описание = 'XY'
  • Ответственный = Мистер Smith '

Мне нужны все «Главные профили» с самой высокой версией, которые имеют ВСЕ подходящие свойства и, конечно, могут иметь больше, которые не совпадают. Это должно быть выполнимо в 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. Main 1 с версией 2
  2. Main 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

На самом деле он получает нужные «Основные профили». Но проблема в том, что извлекаются только два найденных свойства. Мне нужны все свойства из-за дальнейшей обработки.

...