Поиск кортежей в таблице с различным количеством элементов в кортеже - PullRequest
0 голосов
/ 16 мая 2018

У меня длинная таблица с тремя столбцами:

ID, Type, Plan No

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

В исходной таблице под вторым идентификатором (183217760) есть три разных связанных типа (S39905028, S39905133, S39905242) с тремя разными «Планами №». Первый идентификатор (183217488) не будет квалифицирован, поскольку в «плане № 300» отсутствует второй «тип».

Поэтому функция должна возвращать что-то вроде

183217760   200, 300, 400
183218746   200, 300
183218747   200, 300
183219126   200, 300
etc.

Выполнение объединения не будет работать, потому что я не знаю, сколько строк будет объединено. Исходные данные огромны, и есть потенциально кортежи с 20 или более элементами.

Вот исходная таблица:

ID          Type        Plan No
183217488   S39905038   200
183217488   S39905133   200
183217488   S39905133   300
183217760   S39905028   200
183217760   S39905028   300
183217760   S39905028   400
183217760   S39905133   200
183217760   S39905133   300
183217760   S39905133   400
183217760   S39905242   200
183217760   S39905242   300
183217760   S39905242   400
183218106   S39905301   200
183218746   S39905028   200
183218746   S39905028   300
183218746   S39905133   200
183218746   S39905133   300
183218747   S39905028   200
183218747   S39905028   300
183218747   S39905133   200
183218747   S39905133   300
183219126   S39905028   200
183219126   S39905028   300
183219126   S39905133   200
183219126   S39905133   300
183219924   S39905028   200
183219924   S39905133   200
183219924   S39905133   300
183220269   B39910001   200
183220269   S39905012   200
183220269   S39905133   200
183220269   S39905301   200
183220271   B39910001   200
183220271   S39905012   200
183220271   S39905133   200
183220271   S39905301   200

Большое спасибо за любую помощь!

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Я не знаю, насколько эффективно это будет с H2, но, похоже, с вашими примерами работают следующие данные:

with plan_counter as (
  select id, type, count(distinct plan_no) as plan_count
  from plans
  group by id, type
), type_counter as (
  select id, plan_no, count(distinct type) as type_count
  from plans
  group by id, plan_no
), combined as (
  select pc.id, pc.type, tc.plan_no, pc.plan_count, tc.type_count
  from plan_counter pc
    join type_counter tc on tc.id = pc.id
)
select c1.id, group_concat(distinct c1.plan_no order by c1.plan_no separator ',') as plans
from combined c1
where not exists (select *
                  from combined c2
                  where c2.id = c1.id 
                    and c2.plan_count <> c2.type_count)  
group by c1.id
order by c1.id;

Вот онлайн пример: http://rextester.com/WKT8701
(Выше указано использование Postgres, но вместо string_agg() вместо group_concat это то же самое)

0 голосов
/ 16 мая 2018

Решение этой проблемы будет гораздо более эффективным с использованием процедурного алгоритма.

Несмотря на то, что я уверен, что вы можете сделать это с SQL, пробовать это будет ужасно медленно. Лучше использовать SQL, чтобы упорядоченно получать строки и обрабатывать / фильтровать их в своем приложении.

...