Получить уникальную строку с несколькими столбцами в таблице оракулов - PullRequest
0 голосов
/ 27 августа 2018

Привет, у меня есть тег таблиц, который похож на

id   loc_id   org_id   comp1   comp2   comp3   comp4  paper_id
1      5        4       A        C       B     (null)    1
2      6        3       F        D       E     (null)    1
3      5        4       C        B       A     (null)    1
4      6        3       E        F       D     (null)    1

Я хочу получить такой результат, как

id   loc_id   org_id   comp1   comp2   comp3   comp4  paper_id
3      5        4       C        B       A     (null)    1
4      6        3       E        F       D     (null)    1

Примечание. Я хочу, чтобы уникальная строка имела максимальный идентификатор с различными значениями comp1, comp2, comp3, comp4, несмотря на имя столбца, но значение должно быть таким же.

например, если в 1-й строке есть A, B, C в comp1, comp2 и comp3 соответственно и во 2-й строке есть C, B, A в comp1, comp2 и comp3 соответственно Я хочу один ряд.

Я пробовал запрос ниже, и он не возвращает уникальные строки

SELECT DISTINCT loc_id, org_id, comp1, comp2, comp3, comp4, MAX(id)
  FROM tags t
  WHERE t.paper_id = 1
  GROUP BY loc_id, org_id, comp1, comp2, comp3, comp4;

Пожалуйста, помогите спасибо.

Ответы [ 4 ]

0 голосов
/ 29 августа 2018

Вы можете получить желаемые результаты, сгруппировав функции greatest, least и их mean (средние значения) с помощью функции ascii, которая преобразует связанные столбцы в целые числа:

select * 
  from tags
 where id in 
  (
  select max(id)
    from tags
   group by least(ascii(comp1),ascii(comp2),ascii(comp3)),
         greatest(ascii(comp1),ascii(comp2),ascii(comp3)),
         (least(ascii(comp1),ascii(comp2),ascii(comp3))+
          greatest(ascii(comp1),ascii(comp2),ascii(comp3)))/2
  );

Демонстрация SQL Fiddle

0 голосов
/ 27 августа 2018

На первом этапе объедините столбцы compN в указанном порядке.

Вы будете использовать LISTAGG - обратите внимание, что вы используете функции разделитель и NVL, чтобы сделать результат уникальным - вы не хотите интерпретировать (A, A, ноль, ноль) как дубликат (AA, нуль, ноль, ноль)

with t1 as (
select id, nvl(comp1,'-') comp from test union all
select id, nvl(comp2,'-') comp from test union all
select id, nvl(comp3,'-') comp from test union all
select id, nvl(comp4,'-') comp from test)
select id,
listagg(comp,',') within group (order by comp) as comp_key
from t1
group by id
order by 2
;


       ID COMP_KEY                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
---------- --------
         3 -,A,B,C
         1 -,A,B,C
         4 -,D,E,F
         2 -,D,E,F

Остальное так же просто, как группировать на COMP_KEY и выбрать строку из вашего источника.

Вот пример выбора самого высокого значения ID для группы (см. max(id) в t3 подзапросе).

with t1 as (
select id, nvl(comp1,'-') comp from test union all
select id, nvl(comp2,'-') comp from test union all
select id, nvl(comp3,'-') comp from test union all
select id, nvl(comp4,'-') comp from test),
t2 as (
select id,
listagg(comp,',') within group (order by comp) as comp_key
from t1
group by id
), t3 as (
select comp_key, max(id) id from t2
group  by comp_key)
select * from test 
where id in (select id from t3)
order by id
; 

.

        ID     LOC_ID     ORG_ID COMP1 COMP2 COMP3 COMP4        PAPER_ID
---------- ---------- ---------- ----- ----- ----- ---------- ----------
         3          5          4 C     B     A                         1 
         4          6          3 E     F     D                         1 
0 голосов
/ 28 августа 2018

Благодаря @ marmite-bomber у меня сработал следующий запрос,

SELECT comp_key, loc_id, org_id, max_id, 1, sysdate, sysdate
FROM (
  SELECT comp_key, max(id) max_id
  FROM (
    WITH t1 AS (
      SELECT t.id, t.loc_id, t.org_id, nvl(comp1,0) comp FROM tags t WHERE t.paper_id = 1 AND t.paper_id IS NOT NULL UNION 
      SELECT t.id, t.loc_id, t.org_id, nvl(comp2,0) comp FROM tags t WHERE t.paper_id = 1 AND t.paper_id IS NOT NULL UNION
      SELECT t.id, t.loc_id, t.org_id, nvl(comp3,0) comp FROM tags t WHERE t.paper_id = 1 AND t.paper_id IS NOT NULL UNION
      SELECT t.id, t.loc_id, t.org_id, nvl(comp1,0) comp FROM tags t WHERE t.paper_id = 1 AND t.paper_id IS NOT NULL
    )
    SELECT t1.id, t1.loc_id loc_id, t1.org_id org_id, listagg(comp,',') within group (ORDER BY comp) AS comp_key
    FROM t1
    GROUP BY t1.id, t1.loc_id, t1.org_id
  )
  GROUP BY comp_key, loc_id, org_id
) t2, tags tg
WHERE tg.id = t2.max_id;
0 голосов
/ 27 августа 2018

Вот один из вариантов; Посмотрите, подходит ли вам это.

Для этого я собираюсь создать функцию, которая сортирует 4 параметра IN (представляющих comp1, ..., comp4 из ваших данных выборки).

SQL> create or replace function f_sort(p1 in varchar2, p2 in varchar2,
  2                                    p3 in varchar2, p4 in varchar2)
  3  return varchar2
  4  is
  5    /* sorts IN parameters. For example: if IN parameters are a, d, c, b
  6       then RETVAL = a:b:c:d
  7    */
  8    retval varchar2(200);
  9  begin
 10    with temp (p) as
 11      (select p1 from dual union all select p2 from dual union all
 12       select p3 from dual union all select p4 from dual
 13      )
 14    select listagg(p, ':') within group (order by p)
 15      into retval
 16    from temp;
 17
 18    return retval;
 19  end;
 20  /

Function created.

SQL>

Зачем мне это нужно? Чтобы выбрать MAX(ID) для равных комбинаций значений comp1, ..., comp4 - как вы это описали (это делается в inter CTE, ниже в запросе).

SQL> with test (id, loc_id, org_id, comp1, comp2, comp3, comp4) as
  2  (select 1, 5, 4, 'a', 'c', 'b', null from dual union all
  3   select 2, 6, 3, 'f', 'd', 'e', null from dual union all
  4   select 3, 5, 4, 'c', 'b', 'a', null from dual union all
  5   select 4, 6, 3, 'e', 'f', 'd', null from dual
  6  ),
  7  inter as
  8  (select max(id) maxid, f_sort(comp1, comp2, comp3, comp4) srt
  9   from test
 10   group by f_sort(comp1, comp2, comp3, comp4)
 11  )
 12  select t.*
 13  from test t join inter i on i.maxid = t.id
 14  order by t.id;

        ID     LOC_ID     ORG_ID COMP1 COMP2 COMP3 COMP4
---------- ---------- ---------- ----- ----- ----- -----
         3          5          4 c     b     a
         4          6          3 e     f     d

SQL>
...