Нахождение отношений «один к одному» или «один ко многим» между двумя столбцами - PullRequest
1 голос
/ 06 ноября 2019

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

Чтобы использовать круглые числа, существует 600 различных частей, где существует 750 различных отношений часть / семья. Поэтому я пытаюсь создать список номеров деталей, которые не принадлежат только одному семейству.

В качестве примера я создал подмножество данных ниже, на которое я смотрю, а затем и ожидаемый доход.

part_no       family
43d565rfd     ar94
43d000rfd     ur22
43d000rfd     e498
43d565r12     ur24
43d565rfd     ur24
43d365r56     ev69
43d365r56     as56

По сути, из вышеприведенного списка я хочу только вернуть:

part_no
43d000rfd
43d365r56

, потому что они являются частью нескольких семейств.

Ответы [ 3 ]

3 голосов
/ 06 ноября 2019

Вы можете использовать агрегацию и having:

select part_no
from t
group by part_no
having min(family) <> max(family);
1 голос
/ 06 ноября 2019

Используйте предложение HAVING, чтобы отфильтровать детали, принадлежащие одному семейству. Например:

select part_no
from (select distinct part_no, family from t) x
group by part_no
having count(*) > 1

Или:

select part_no
from t
group by part_no
having count(distinct family) > 1
0 голосов
/ 06 ноября 2019

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

SQL> WITH YOUR_TABLE(part_no, family) AS
  2  (SELECT '43d565rfd',     'ar94' FROM DUAL UNION ALL
  3  SELECT '43d000rfd',     'ur22' FROM DUAL UNION ALL
  4  SELECT '43d000rfd',     'e498' FROM DUAL UNION ALL
  5  SELECT '43d565r12',     'ur24' FROM DUAL UNION ALL
  6  SELECT '43d565rfd',     'ur24' FROM DUAL UNION ALL
  7  SELECT '43d365r56',     'ev69' FROM DUAL UNION ALL
  8  SELECT '43d365r56',     'as56' FROM DUAL)
  9  SELECT
 10      PART_NO,
 11      FAMILY,
 12      CNT   AS TOTAL_FAMILIES
 13  FROM
 14      (
 15          SELECT
 16              PART_NO,
 17              FAMILY,
 18              COUNT(1) OVER(
 19                  PARTITION BY PART_NO
 20              ) AS CNT
 21          FROM YOUR_TABLE
 22      ) WHERE CNT > 1
 23  ORDER BY PART_NO;

PART_NO   FAMI TOTAL_FAMILIES
--------- ---- --------------
43d000rfd ur22           2
43d000rfd e498           2
43d365r56 ev69           2
43d365r56 as56           2
43d565rfd ar94           2
43d565rfd ur24           2

6 rows selected.

SQL>

или Если вы хотите, чтобы семьи были в списке, разделенном запятыми, используйтеследующее:

SQL>
SQL> WITH YOUR_TABLE(part_no, family) AS
  2  (SELECT '43d565rfd',     'ar94' FROM DUAL UNION ALL
  3  SELECT '43d000rfd',     'ur22' FROM DUAL UNION ALL
  4  SELECT '43d000rfd',     'e498' FROM DUAL UNION ALL
  5  SELECT '43d565r12',     'ur24' FROM DUAL UNION ALL
  6  SELECT '43d565rfd',     'ur24' FROM DUAL UNION ALL
  7  SELECT '43d365r56',     'ev69' FROM DUAL UNION ALL
  8  SELECT '43d365r56',     'as56' FROM DUAL)
  9  SELECT
 10      PART_NO,
 11      LISTAGG(FAMILY, ',') WITHIN GROUP(
 12          ORDER BY
 13              1
 14      ) AS FAMILIES,
 15      COUNT(1) AS TOTAL_FAMILIES
 16  FROM
 17      YOUR_TABLE
 18  GROUP BY
 19      PART_NO
 20  HAVING
 21      COUNT(DISTINCT FAMILY) > 1
 22  ORDER BY
 23      PART_NO
 24  ;

PART_NO   FAMILIES             TOTAL_FAMILIES
--------- -------------------- --------------
43d000rfd e498,ur22                         2
43d365r56 as56,ev69                         2
43d565rfd ar94,ur24                         2

SQL>

Ура !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...