J'ai une table stockant les enregistrements parent/enfant en tant que tels:
+-------+------------+---------+---------+------------+-----------+
|custid | custname | deptid | company |parentcustid| enrolled |
+=======+============+=========+=========+============+===========+
| 7060 | Sally | AB1 | comp1 | null | 1 |
| 6953 | Ajit | AB7 | comp2 | 7060 | 1 |
| 6957 | Rahul | DE1 | comp3 | 7060 | 1 |
| 6958 | uday | TG6 | comp4 | 7060 | 1 |
| 6959 | john | HY7 | comp5 | 7060 | 1 |
| 6960 | netaji | HY5 | comp6 | 7060 | 1 |
| 6961 | prakriti | GT6 | comp7 | 7060 | 1 |
| 6962 | sachin | KL7 | comp8 | 7060 | 0 |
| 6963 | santosh | KK5 | comp9 | 7060 | 1 |
| 6964 | Ravi | PP0 | comp10 | 7060 | 1 |
+-------+------------+---------+---------+------------+-----------+
Est-il possible de renvoyer des enregistrements où l'enregistrement parent est inscrit et l'enregistrement enfant associé n'est pas inscrit?
Cela renvoie ce dont j'ai besoin pour 1 client spécifique:
select a.custid, a.custname, a.deptid, a.company, a.parentcustid, a.enrolled
from customer a
where a.company = 'comp1' and a.Enrolled = 1
union all
select a.custid, a.custname, a.deptid, a.company, a.parentcustid, a.enrolled
from customer a
where a.parentcustid= 7060 and b.Enrolled = 0
+-------+------------+---------+---------+------------+-----------+
|custid | custname | deptid | company |parentcustid| enrolled |
+=======+============+=========+=========+============+===========+
| 7060 | Sally | AB1 | comp1 | null | 1 |
| 6962 | sachin | KL7 | comp8 | 7060 | 0 |
+-------+------------+---------+---------+------------+-----------+
Comment puis-je structurer la requête pour renvoyer ce type d'ensemble de résultats pour tous les enregistrements enfants parents dans la table?
Si vous n'avez qu'un seul niveau d'enfants, vous pouvez rejoindre les tables
SELECT
a.custid, a.custname, a.deptid, a.company,
b.custid AS bcustid, b.custname AS bcustname, b.deptid AS bdeptid, b.company AS bcompany
FROM
customer a
LEFT JOIN customer b
ON a.custid = b.parentcustid AND b.Enrolled = 0
WHERE
a.parentcustid IS NULL AND a.Enrolled = 1
De cette façon, vous ne perdez pas la relation entre le parent et le dossier enfant.
Étant donné que vous savez que les parents sont inscrits et les enfants non, le fait de conserver la colonne enrolled
n'ajoute aucune nouvelle information.
Si vous souhaitez conserver la forme d'origine de votre tableau de résultats, utilisez une colonne supplémentaire pour le tri
SELECT
custid, custname, deptid, company, parentcustid, enrolled,
10 * custid AS orderKey
FROM customer
WHERE parentcustid IS NULL AND Enrolled = 1
UNION ALL
SELECT
custid, custname, deptid, company, parentcustid, enrolled,
10 * parentcustid + 1 AS orderKey
FROM customer
WHERE parentcustid IS NOT NULL AND Enrolled = 0
ORDER BY orderKey, custid
Notez que cet ORDER BY est appliqué à l'ensemble de l'union, pas seulement au deuxième SELECT. Ainsi, les enfants sont toujours répertoriés juste en dessous de leurs parents.
Au fait, multiplier la clé par 2 suffit pour obtenir l'effet souhaité pour la clé de commande. Il s'affiche simplement mieux si vous multipliez par 10. Si vos identifiants client comportent toujours un maximum de 4 chiffres, vous pouvez également utiliser 10000 * custid
pour les parents et 10000 * parentcustid + custid
pour les enfants et commandez uniquement par orderKey
pour obtenir des enregistrements bien ordonnés.
Une façon courante de le faire dans SQL Server est d'utiliser un CTE récursif :
Voici vos données de test en encart:
CREATE TABLE #yourmom
(
custid INT,
custname VARCHAR(10),
deptid VARCHAR(3),
company VARCHAR(10),
parentcustid INT,
enrolled BIT
)
INSERT #yourmom ( custid, custname, deptid, company, parentcustid, enrolled )
SELECT x.custid, x.custname, x.deptid, x.company, x.parentcustid, x.enrolled
FROM ( VALUES ( 7060, 'Sally ', 'AB1', 'comp1 ', NULL, 1 ),
( 6953, 'Ajit ', 'AB7', 'comp2 ', 7060, 1 ),
( 6957, 'Rahul ', 'DE1', 'comp3 ', 7060, 1 ),
( 6958, 'uday ', 'TG6', 'comp4 ', 7060, 1 ),
( 6959, 'john ', 'HY7', 'comp5 ', 7060, 1 ),
( 6960, 'netaji ', 'HY5', 'comp6 ', 7060, 1 ),
( 6961, 'prakriti', 'GT6', 'comp7 ', 7060, 1 ),
( 6962, 'sachin ', 'KL7', 'comp8 ', 7060, 0 ),
( 6963, 'santosh ', 'KK5', 'comp9 ', 7060, 1 ),
( 6964, 'Ravi ', 'PP0', 'comp10', 7060, 1 )
) AS x ( custid, custname, deptid, company, parentcustid, enrolled );
Et voici comment un CTE récursif le rechercherait:
WITH yourdad
AS ( SELECT y.custid, y.custname, y.deptid, y.company, y.parentcustid, y.enrolled
FROM #yourmom AS y
WHERE y.parentcustid IS NULL
AND y.enrolled = 1
UNION ALL
SELECT ym2.custid, ym2.custname, ym2.deptid, ym2.company, ym2.parentcustid, ym2.enrolled
FROM yourdad AS yd
JOIN #yourmom AS ym2
ON ym2.parentcustid = yd.custid
AND ym2.enrolled = 0 )
SELECT *
FROM yourdad;
Il y a quelques Great Posts® écrits à leur sujet:
Le grand défunt Dwain Camps
J'espère que cela t'aides!