2 votes

SQL sélectionne les enregistrements dont les valeurs d'un champ sont similaires à celles d'un autre champ.

Disons que j'ai un tableau pour une nomenclature qui ressemble à ce qui suit :

+----------+-------------+
| ParentNo | ComponentNo |
+----------+-------------+
| AAA      |         101 |
| AAA      |         102 |
| BBB      |         201 |
| BBB      |         202 |
| CCC      |         101 |
| CCC      |         201 |
| CCC      |         301 |
| DDD      |         101 |
| DDD      |         102 |
+----------+-------------+

Je voudrais écrire une requête qui trouve cualquier des numéros de parents qui partagent des ensembles de composants identiques. Je suis flexible sur le résultat, mais mon idée initiale est qu'il serait similaire à :

+----------+---------+
| ParentNo | Matched |
+----------+---------+
| AAA      | DDD     |
| DDD      | AAA     |
+----------+---------+

Il existe plusieurs façons de trouver des enregistrements individuels qui partagent la même valeur pour un ou plusieurs champs, comme indiqué dans la section "Recherche d'enregistrements". Recherche de valeurs dupliquées dans une table SQL . Mais je ne veux renvoyer un résultat que lorsque todo les composants de deux parents différents correspondent.

La solution la plus proche que j'ai vue est la suivante SQL sélectionne les lignes dont la valeur d'une colonne est commune à une autre colonne de critère . Cela ne répond pas à mon besoin car il faut fournir un ensemble de numéros de composants spécifiques. J'essaie d'éviter de saisir manuellement les numéros de composants pour chaque numéro de parent individuel (les ensembles de données avec lesquels je travaille contiennent des dizaines de millions d'enregistrements).

J'ai l'impression qu'une forme de requête récursive pourrait être appropriée dans cette situation, mais mes tentatives n'ont pas donné lieu à des requêtes qui semblent être sur la bonne voie.

0voto

Vamsi Prabhala Points 39045

Vous pouvez utiliser LISTAGG pour concaténer tous les composants d'un parent. Ensuite, utilisez un self join pour vérifier que les parents ont les mêmes composants.

with grouped_comps as (
select parentno, LISTAGG(cast(componentno as varchar(10000)), ',') WITHIN GROUP(ORDER BY componentno) as comp_all
from t
group by parentno)
select g1.parentno,g2.parentno
from grouped_comps g1
join grouped_comps g2 on g1.parentno<>g2.parentno and g1.comp_all=g2.comp_all

0voto

Esperento57 Points 8045

Essayez quelque chose comme ceci

--Create temprary table with rownumber
with tmp0 as (
select f0.*, rownumber() over(partition by parentno order by componentno) rang, (select count(*) from jgrun.tmp1222 f1 where f1.parentno=f0.parentno) as nb   
from yourlib.yourtable f0
),

--Create temporary table recurse with componentno concatenante
tmp1 (parentno, componentno, listcomponentno, rang, nb, rgcal) as (
select parentno, componentno,  cast(tmp0.componentno  as varchar(500)), rang, nb, 1 from tmp0
union all
select tmp0.parentno,  tmp0.componentno,  cast(tmp0.componentno || ', ' || tmp1.listcomponentno as varchar(500)), tmp0.rang, tmp0.nb, tmp1.rgcal+1 
from tmp0 inner join tmp1 on tmp0.parentno=tmp1.parentno  and tmp1.rang-1=tmp0.rang
),
--Select last concatenation
tmp2 as (
select * from tmp1
where nb=rgcal
)
--Cross parent different and same list component no
select f1.parentno, f2.parentno, f1.listcomponentno
 from tmp2 f1 inner join tmp2 f2 on f1.parentno<>f2.parentno and f1.listcomponentno=f2.listcomponentno

-1voto

LONG Points 3372
 SELECT Parent.ParentNo,Child.ParentNo FROM 
 TABLE AS Parent
 LEFT JOIN TABLE as Child
 ON Child.ComponentNo = Parent.ComponentNo
 Where Parent.ParentNo != Child.ParentNo

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X