postgres - одна запись с одной или несколькими таблицами соединения - PullRequest
0 голосов
/ 07 мая 2020

У меня есть две таблицы a и b. Где основная таблица - это «a», из которой я хочу выбрать, а таблица «b» предназначена для фильтрации. Ниже приведен образец таблицы с некоторыми данными.

create table a (
   id varchar primary key,
   name varchar,
   p varchar[]
);

insert into a (id, name, p) values 
 ('1', 'v1', array['p1']),
 ('2', 'v2', array['p1','p2']),
 ('3', 'v3', array['p2','p3']);


create table b (
   p varchar,
   x varchar
);

insert into b(p, x) values
   ('p1', 'x1'),
   ('p2', 'x2'),
   ('p3', 'x1'),
   ('p3', 'x3'),
   ('p1', 'x2');

Мне нужна только одна строка из таблицы a на основе соединения по столбцу p и фильтрации по x. Я пробовал несколько вариантов, он работает, когда у меня есть запись один к одному в a и b, но когда у меня есть одна или несколько записей, я получаю несколько записей.

select a.* from a,b where b.p=any(a.p) and b.x='x2';

Результат, который я получаю:

id  name   p  
-----------------
1   v1     p1  
2   v2     p1,p2  
2   v2     p1,p2  
3   v3     p2,p3  

Я хочу

id  name   p  
-----------------
1   v1     p1   
2   v2     p1,p2  
3   v3     p2,p3  

Также я ожидаю, что таблица 'a' будет иметь миллионы строк, а 'b' будет иметь только несколько , поэтому запрос должен быть работать эффективно.

1 Ответ

0 голосов
/ 07 мая 2020

Поскольку вам нужны только столбцы из таблицы, a используйте условие exists, а не соединение:

select a.* 
from a
where exists (select *
              from b
              where b.p = any(a.p) 
                and b.x='x2');

Однако это будет довольно сложно оптимизировать.

Другой вариант - если не слишком много строк соответствует критериям соединения - это применить отдельный результат к результату соединения.

В этом случае можно использовать индекс GIN в столбце массива:

create index on a using gin (p);

select distinct a.* 
from a
  join b on a.p @> array[b.p]
where b.x= 'x2';
...