oba*_*sta 5 join sql-server hierarchy
我有一个存储父/子记录的表,如下所示:
+-------+------------+---------+---------+------------+-----------+
|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 |
+-------+------------+---------+---------+------------+-----------+
Run Code Online (Sandbox Code Playgroud)
是否可以返回已登记父记录而未登记相关子记录的记录?
这将返回我对 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 |
+-------+------------+---------+---------+------------+-----------+
Run Code Online (Sandbox Code Playgroud)
如何构造查询以返回表中所有父子记录的该类型的结果集?
在 SQL Server 中执行此操作的常用方法是使用递归 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 );
Run Code Online (Sandbox Code Playgroud)
这是递归 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;
Run Code Online (Sandbox Code Playgroud)
有一些关于它们的 Great Posts®:
已故伟大的Dwain Camps
希望这可以帮助!
如果你只有一个级别的孩子,你可以加入表格
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
Run Code Online (Sandbox Code Playgroud)
像这样,您不会丢失父记录和子记录之间的关系。
由于您知道父母已注册而孩子未注册,因此重新访问该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
Run Code Online (Sandbox Code Playgroud)
请注意,此 ORDER BY 应用于整个联合,而不仅仅是第二个 SELECT。像这样,孩子总是列在他们父母的下面。
顺便说一句,将键乘以 2 就足以获得所需的顺序键效果。如果乘以 10,它只会显示得更好。如果您的客户 ID 始终最多为 4 位数字,您还可以将其10000 * custid用于父级和10000 * parentcustid + custid子级,并且仅通过orderKey排序来获得有序记录。
| 归档时间: |
|
| 查看次数: |
38756 次 |
| 最近记录: |