そのような親/子レコードを格納するテーブルがあります:
+-------+------------+---------+---------+------------+-----------+
|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 |
+-------+------------+---------+---------+------------+-----------+
親レコードが登録済みで、関連する子レコードが未登録のレコードを返すことはできますか?
これにより、特定の顧客1人に必要なものが返されます。
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 |
+-------+------------+---------+---------+------------+-----------+
テーブル内のすべての親子レコードに対してそのタイプの結果セットを返すようにクエリを構造化するにはどうすればよいですか?
子供のレベルが1つしかない場合は、テーブルに参加できます
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
このようにして、親レコードと子レコードの関係を失うことはありません。
親は登録されており、子供は登録されていないことがわかっているため、enrolled
列を再試行しても新しい情報は追加されません。
元の結果テーブルの形状を保持する場合は、並べ替えに追加の列を使用します
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
このORDER BYは、2番目のSELECTだけでなく、ユニオン全体に適用されることに注意してください。このように、子供は常に親のすぐ下にリストされます。
ところで、キーを2倍すると、注文キーに必要な効果が得られます。 10を掛けると、見栄えがよくなります。顧客IDが常に最大4桁の場合は、親に10000 * custid
を使用し、子に10000 * parentcustid + custid
を使用して、orderKey
を使用して、順序の整ったレコードを取得します。
SQL Serverでこれを行う一般的な方法は、 Recursive CTE を使用することです。
挿入したテストデータは次のとおりです。
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 );
そして、これが再帰CTEがそれを探す方法です:
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;
それらについて書かれたいくつかのGreatPosts®があります:
後期の偉大 ドウェインキャンプ
お役に立てれば!