Сопоставить повторяющееся значение из 2 столбцов и 1 уникальное значение из 1 столбца mysql - PullRequest
1 голос
/ 12 июля 2020

У меня есть эта таблица, вот моя db Fiddle

CREATE TABLE table1 (
  `ID` VARCHAR(100),
  `Val` VARCHAR(100),
  `Val2` VARCHAR(100),
  `Val3` VARCHAR(100)
);

INSERT INTO table1
  (`ID`, `Val`, `Val2`, `Val3`)
VALUES
  ('1','100','200','90'),
  ('2','100','200','10'),
  ('3','100','200','20'),
  ('4','20','100','55'),
  ('5','20','100','10'),
  ('6','112','100','20'),
  ('7','112','100','20'),
  ('8','90','200','90'),
  ('9','30','90','180'),
  ('10','30','90','29');

Я хочу получить результат с этим условием

  1. Val нужно было дублировать И
  2. Val2 должен быть дублирован И

После того, как я получил повторяющееся значение, теперь мне нужно проверить val3 из повторяющегося значения, если значение val3 имело уникальное значение из предыдущего агрегата

Я пробовал с этим запросом

SELECT
    t1.* 
FROM
    table1 t1 
WHERE
    EXISTS (
    SELECT
        1 
    FROM
        table1 
    WHERE
        ID <> t1.ID 
        AND Val = t1.Val 
        AND Val2 = t1.Val2 
    ) 
    AND NOT EXISTS (
    SELECT
        1 
    FROM
        table1 
    WHERE
        Val = t1.Val 
        AND Val2 = t1.Val2 
    AND Val3 IN ( 
    SELECT Val3 
    FROM table1 
    GROUP BY Val3 
    HAVING count( * ) > 1 
    ) 
)

Я ожидаю, что результат будет таким

ID  Val Val2    Val3
1   100 200 90
2   100 200 10
3   100 200 20
4   20  100 55
5   20  100 10
9   30  90  180
10  30  90  29

Но я получил результат вроде это

ID  Val Val2    Val3
9   30  90  180
10  30  90  29

Пример 2

INSERT INTO table1
  (`ID`, `Val`, `Val2`, `Val3`)
VALUES
  ('1','100','200','90'),
  ('2','100','200','10'),
  ('3','100','200','20'),
  ('19','100','200','20'),
  ('4','20','100','55'),
  ('5','20','100','10'),
  ('6','112','100','20'),
  ('7','112','100','20'),
  ('8','90','200','90'),
  ('9','30','90','180'),
  ('10','30','90','29');

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

ID  Val Val2    Val3
1   100 200 90
2   100 200 10
4   20  100 55
5   20  100 10
9   30  90  180
10  30  90  29

dbfiddle 2

Пример 3

INSERT INTO table1
  (`ID`, `Val`, `Val2`, `Val3`)
VALUES
  ('1','100','200','aa'),
  ('2','100','200','aa'),
  ('3','100','200','aa'),
  ('19','100','200','ab'),
  ('4','20','100','SD2'),
  ('5','20','100','SD1'),
  ('6','112','100','aa'),
  ('7','112','100','ab'),
  ('8','90','200','aa'),
  ('9','30','90','SF2'),
  ('10','30','90','SF1');

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

ID  Val Val2    Val3

4   20  100 SD2
5   20  100 SD1
6   112 100 aa
7   112 100 ab
9   30  90  SF2
10  30  90  SF1

Некоторых людей могут спутать с образцом 3, поэтому вот примечания к образцу 3:

Для этого случая ID 19 в примере 3 было то же значение со столбцами val и val2 для идентификаторов 1, 2, 3 (100 и 200), но эти идентификаторы (1, 2, 3) имели такое же значение aa в val3, поэтому id 1,2 , 3 должны быть исключены, потому что использование этих идентификаторов не соответствует последнему условию (val, val2, val3) является уникальным. Идентификатор 19 в порядке, но столбец val dan val2 с повторяющимся значением, равным 1, 2 и 3, уже исключен, это означает, что идентификатор 19 не имеет повторяющихся значений для столбцов val и val2. если в примере 3 были другие данные, такие как '200', '100', '200', 'ae', идентификатор 19 будет включен в результат, потому что он имеет повторяющееся значение рядом с идентификаторами 1,2 и 3.

для образца 3 ID 19 будет включен, если данные в таблице 1 были такими

Образец 3 (другой случай)

INSERT INTO table1
  (`ID`, `Val`, `Val2`, `Val3`)
VALUES
  ('1','100','200','aa'),
  ('2','100','200','aa'),
  ('3','100','200','aa'),
  ('19','100','200','ab'),
  ('200','100','200','ae'),
  ('4','20','100','SD2'),
  ('5','20','100','SD1'),
  ('6','112','100','aa'),
  ('7','112','100','ab'),
  ('8','90','200','aa'),
  ('9','30','90','SF2'),
  ('10','30','90','SF1');

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

ID  Val Val2    Val3

4   20  100 SD2
5   20  100 SD1
19  100 200 ab
200 100 200 ae
6   112 100 aa
7   112 100 ab
9   30  90  SF2
10  30  90  SF1

Ответы [ 3 ]

1 голос
/ 12 июля 2020

Присоедините таблицу к запросам, которые применяют ваши условия:

select distinct t.*
from (
  select val, val2
  from table1
  group by val, val2
  having count(*) > 1
) t1 
inner join (
 select val, val2, val3
  from table1
  group by val, val2, val3
  having count(*) = 1
) t2 
on t2.val = t1.val and t2.val2 = t1.val2
inner join (
 select val, val2, val3
  from table1
  group by val, val2, val3
  having count(*) = 1
) t3 
on t3.val = t1.val and t3.val2 = t1.val2 and t3.val3 <> t2.val3
inner join table1 t on t2.val = t.val and t2.val2 = t.val2 and t.val3 in (t2.val3, t3.val3)

См. demo1 , demo2 , demo3 , demo4 .

1 голос
/ 15 июля 2020

Как @GMB довольно упрощенно сказал в своем ответе, вам нужны строки, (val, val2) кортеж которых не уникален, а (val, val2, val3) уникален.

Следующий запрос должен выполнить sh это очень легко:

   select t.*
from table1 t
inner join
(
select t1.val, t1.val2
from table1 t1
 inner join
  (select val,val2,val3
    from table1
    group by val,val2,val3
    having count(val3) = 1
  ) t2
 on t1.val = t2.val and t1.val2 = t2.val2 and t1.val3 = t2.val3
 group by t1.val, t1.val2
 having count(distinct t1.id) > 1
) tmp
on tmp.val = t.val and tmp.val2 = t.val2
inner join
(select val,val2,val3
    from table1
    group by val,val2,val3
    having count(val3) = 1
  ) t3
 on t.val = t3.val and t.val2 = t3.val2 and t.val3 = t3.val3

Найдите ссылку на скрипт для Sample1 , Sample2 , Sample3 и Sample4 .

1 голос
/ 12 июля 2020

Насколько я понимаю ваш вопрос, вам нужны строки, (val, val2) кортеж которых не уникален, а (val, val2, val3) уникален.

Вот один из способов express этого, отфильтровав набор данных с помощью коррелированных подзапрос:

select t1.*
from table1 t1
where 
    (
        select count(*) 
        from table1 t2 
        where t2.val = t1.val and t2.val2 = t1.val2
    ) > 1
    and (
        select count(*)
        from table1 t2
        where t2.val = t1.val and t2.val2 = t1.val2 and t2.val3 = t1.val3
    ) = 1
order by id

Для повышения производительности рассмотрите индекс на (val, val1, val2) (здесь имеет значение порядок столбцов в индексе).

Если вам посчастливилось запустить MySQL 8.0, это можно выразить проще и эффективнее с помощью оконных функций:

select id, val, val2, val3
from (
    select 
        t1.*,
        count(*) over(partition by val, val2) cnt_1,
        count(*) over(partition by val, val2, val3) cnt_2
    from table1 t1
) t
where cnt_1 > 1 and cnt_2 = 1
...