Внутри табличного подзапроса идентичных комбинаций - PullRequest
0 голосов
/ 14 января 2012

Я хотел бы выбрать группы, которые имеют одинаковые атрибуты из таблицы.Например, моя таблица похожа на следующую

facs_run_id |  fcj_id
    1       |     17
    1       |     4
    1       |     12
    2       |     17
    2       |     4
    2       |     12
    3       |     17
    3       |     12
    3       |     10

. В этой таблице каждая facs_run_id имеет различные комбинации fcj_id, некоторые из них разделены между facs_run_id числами, а другие нет.Например, выше facs_run_id 1 и 2 идентичны, в то время как 3 имеет общие fcj_id, но не идентичны 1 и 2.Я хотел бы сделать запрос:

  1. собрать все fcj_id из определенного facs_run_id
  2. найти все facs_run_id, которые имеют точно такую ​​же комбинацию fcj_id.

Здесь я хочу найти все facs_run_id, которые в fcj_id комбинациях равны facs_run_id: 1, поэтому он должен вернуть 2 (или 1 & 2).

Я могу получить те, которые пропускают определенные fcj_id и даже найти, которые fcj_id отсутствуют с этим:

SELECT facs_run_id 
FROM   facs_panel 
EXCEPT 
SELECT fcj_id 
FROM   facs_panel 
WHERE  facs_run_id = 2;

или с этим:

SELECT row(fp.*, fcj.fcj_antigen, fcj.fcj_color) 
FROM   facs_panel fp 
       LEFT OUTER JOIN facs_conjugate_lookup fcj ON fcj.fcj_id = fp.fcj_id
WHERE  fp.fcj_id  in ( SELECT fp.fcj_id 
                       FROM   facs_panel fp 
                       WHERE  fp.facs_run_id = 1);

НоЯ не могу сделать запрос, который возвращает IDENTICAL facs_run_id.Я полагаю, это можно рассматривать как способ поиска агрегированных дубликатов, но я не знаю, как это сделать.Будем весьма благодарны за любые предложения или указатели (или лучший способ создать таблицу, если этот тип запроса не будет работать).

1 Ответ

0 голосов
/ 11 апреля 2012

Это довольно легко с парой CTE:

with f1 as (select
                facs_run_id,
                array_agg(fcj_id) as flist
              from facs_panel
              group by facs_run_id),
     f2 as (select flist, count(*)
              from f1
              group by flist
              having count(*) > 1)
select f2.flist, f1. facs_run_id
  from f2
  join f1 on (f2.flist = f1.flist)
  order by flist, facs_run_id;

Данные из вопроса, проходящие через этот запрос, дают:

   flist   | facs_run_id 
-----------+-------------
 {4,12,17} |           1
 {4,12,17} |           2
(2 rows)
...