Найти родительский идентификатор, когда все дети имеют одинаковое значение - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть данные, которые выглядят примерно так:

                 Table C
id | end_time
-------------
1    '2019-01-01'
2    '2020-01-01'    
3    '2019-07-01'    

                 Table F
id | parent_id
12 |    1
13 |    1

21 |    2
22 |    2

31 |    3
32 |    3
33 |    3
34 |    3



                  Table oui
rel_id | Product Version
1             '2'
12            '2'
13            '1'

2             '1'
21            '2'
22            '1'

3             '2'
31            '1'
32            '1'
33            '1'
34            '1'

Отношение данных: c .id = f.parent_id

c .id или f.id = oui.rel_id

Я пытаюсь найти, где rel_id для C в таблице oui - версия продукта родителя - 2, но ВСЕ дочерние - версия 1.

Я нашел похожий вопрос здесь: Найти идентификатор родителя, где все дети в точности совпадают с , но не может полностью адаптировать его к этому варианту использования.

Ожидаемый результат:

c.id
----
 3

Причина: у обоих c .id 1/2 есть дети, у которых есть по крайней мере 1 элемент в версии продукта 2.

Ответы [ 3 ]

1 голос
/ 14 апреля 2020

Попробуйте:

select 
 t1.id 
 from c "t1" 
 inner join oui "t2" on t2.rel_id=t1.id 
 where t2.product_version='2' -- product_version for Parent
 and 
 (select 
 count(*) 
 from f "t3" 
 inner join oui t4 on t4.rel_id=t3.id 
 where t4.product_version !='1' -- product_version  for Child
 and t3.parent_id=t1.id
 )=0

Примечание. Вышеупомянутый запрос будет работать идеально, если ID в таблице C и ID в таблице F не совпадает и rel_id столбец в таблице oui имеет уникальные значения.

1 голос
/ 14 апреля 2020

Вы хотите получить C записей с версией продукта = 2, для которых существует F записей с версией продукта = 1 и не существует F записей с версией продукта <> 1.

Надеюсь Не знаю, почему есть отдельная таблица OUI. Можно было бы ожидать, что версия продукта будет представлять собой простой столбец в таблицах C и F.

Итак, давайте используем два предложения with, чтобы перейти к лучшим таблицам: -)

with better_c as (select c.*, oui.product_version from c join oui on oui.rel_id = c.id)
   , better_f as (select f.*, oui.product_version from f join oui on oui.rel_id = f.id)

Реальный запрос может быть записан с помощью INTERSECT и EXECPT:

with ...
select id from better_c where product_version = 2
intersect
select parent_id from better_f where product_version = 1
except
select parent_id from better_f where product_version <> 1;

То же с [NOT] EXISTS:

with ...
select id 
from better_c 
where product_version = 2
and exists
 (select null from better_f where product_version = 1 and parent_id  = better_c.id)
and not exists
 (select parent_id from better_f where product_version <> 1 and parent_id  = better_c.id);

То же с [NOT] IN :

with ...
select id 
from better_c 
where product_version = 2
and id in (select parent_id from better_f where product_version = 1)
and id not in (select parent_id from better_f where product_version <> 1);
1 голос
/ 14 апреля 2020

Попробуйте это ниже logi c -

ДЕМО ЗДЕСЬ

SELECT ID FROM C
WHERE ID NOT IN
(
    SELECT C.ID
    FROM C
    INNER JOIN F ON C.id = F.parent_id
    INNER JOIN oui ON F.ID = Oui.rel_id
    WHERE C.ID = CAST(oui.Product_Version AS INT)
    -- by default your column "Product Version" should be INT in table oui
)

Проблема, которую вы упомянули в комментарии ниже, вы можете попробовать это противоположное преобразование как ниже-

SELECT ID FROM C
WHERE ID NOT IN
(
    SELECT C.ID
    FROM C
    INNER JOIN F ON C.id = F.parent_id
    INNER JOIN oui ON F.ID = Oui.rel_id
    WHERE CAST(C.ID AS VARCHAR) = oui.Product_Version
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...