所以我想说我有一张桌子,BMST。我使用此查询来查找结果集:
SELECT PARENT,
CHILD,
LEVEL,
QTY
FROM BMST
WHERE PARENT = '111'
在结果集中有PARENT部件号,以及CHILD部件号,例如:
PARENT | CHILD | LEVEL | QTY
-----------------------------
111 | 222 | 0 | 2
111 | 333 | 0 | 1
111 | 444 | 0 | 1
该表提供了用于制作PARENT部件的所有CHILD部件的信息,以及每个PARENT部件中使用的QUILD OF CHILD部件。 LEVEL列的值为'0',因为部分'111'是我们关心的原点部分。我们不关心部分'111'是另一个较大的PARENT部分的CHILD部分。
如果CHILD部件由较小的CHILD部件组成,它们也可能是PARENT部件。例如,此查询:
SELECT PARENT,
CHILD,
LEVEL,
QTY
FROM BMST
WHERE PARENT = '222'
将返回:
PARENT | CHILD | LEVEL | QTY
-----------------------------
222 | 555 | 1 | 1
222 | 666 | 1 | 1
222 | 777 | 1 | 1
此新表中的LEVEL值为'1',因为部分'222'是LEVEL ='0'PARENT部分的CHILD部分。
更进一步,部分'222'的CHILD部分本身可能有CHILD部分,因此对'777'部分的类似查询将返回:
PARENT | CHILD | LEVEL | QTY
-----------------------------
777 | 999 | 2 | 2
我的问题是,是否可以创建一个返回第一个结果集的查询,然后检查该结果集中的所有CHILD部分值,看看它们是否有任何CHILD部分,然后检查结果更多CHILD部件等的CHILD部件,直到没有更多CHILD部件,然后UNION那些进入第一个结果集的部件,如下所示:
PARENT | CHILD | LEVEL | QTY
-----------------------------
111 | 222 | 0 | 2
222 | 555 | 1 | 1
222 | 777 | 1 | 1
777 | 999 | 2 | 2
222 | 888 | 1 | 1
111 | 333 | 0 | 1
111 | 444 | 0 | 1
LEVEL值需要在查询进一步深入的每一步中递增,最终结果集应显示进入请求的PARENT部分的每个部分。
有没有办法在SQL中执行所有这些操作?或者我是否必须使用VB6或其他程序来遍历循环?感谢任何反馈。
答案 0 :(得分:2)
您应该查看SELF JOIN而不是联合。您可以将表连接到自身,从而链接父和子。儿童身份证。它将需要一个子句来消除与自己连接的行。 child
ID本质上是示例中的主键,parent
ID充当外键的一种。
以下是使用Microsoft Access完成此操作的示例,因为它非常方便:
表BMST:
PARENT CHILD LEVEL QTY
111 222 0 2
111 333 0 1
111 444 0 1
222 555 1 1
222 666 1 1
222 777 1 1
555 aaa 2 11
555 aab 2 12
aaa xxx 3 100
aab www 3 111
aaa UUU 3 121
<强>查询:强>
SELECT c.PARENT, c.CHILD, c.[LEVEL], c.QTY
FROM BMST AS P, BMST AS C
WHERE P.child = C.parent
and P.parent <> C.parent
ORDER BY c.level;
<强>结果:强>
PARENT CHILD LEVEL QTY
222 777 1 1
222 666 1 1
222 555 1 1
555 aab 2 12
555 aaa 2 11
aaa UUU 3 121
aab www 3 111
aaa xxx 3 100
请注意,我发明了一些额外的记录来证明这涵盖了层次结构的所有级别。查询是不完美的,因为最顶层的父项被排除(没有父项本身),这可能是通过使用外部联接来解决的。
奇怪的是,这个特定示例查询的结果非常类似于表本身,但这是在应用任何其他条件之前,例如您真正感兴趣的父元素。
此问题可提供更多信息:Explanation of self-joins
答案 1 :(得分:1)
要做你想做的事,你需要一些叫做递归的东西。当然,你可以逐行解析它(使用T-SQL,或使用VB,或者你熟悉的任何语言),但是,这个问题(递归)很容易通过名为Common Table Expressions
或{的东西来解决。 {1}}。
使用CTE
你可以结合你的结果,所以在这种情况下,孩子可以成为父母的父母与孩子的关系。
我已创建此脚本以向您展示如何操作。首先我填充一些临时表,之后我使用CTE
CTE
Blow是if object_id('tempdb..#BMST') is not null
begin
drop table #BMST
end
create table #BMST (
PARENT varchar(5)
, CHILD varchar(5)
, LEVEL varchar(5)
, QTY varchar(5)
)
insert into #BMST
select '111', '222', 0, 2
union all select '111', '333', 0, 1
union all select '111', '444', 0, 1
union all select '222', '555', 1, 1
union all select '222', '666', 1, 1
union all select '222', '777', 1, 1
union all select '777', '999', 2, 2
。 CTE
始终必须是第一个语句,因此使用分号。之后开始Common Table Expression
施工。 with xxx as ()
是一个虚构的名字,可以是任何东西。
(在此示例中,我使用新的colom results
向您显示新级别)
SECONDLEVEL
如您所见,我正在使用;with results as (
select *
, 0 as SECONDLEVEL
from #BMST b
union all
select b.*
, r.SECONDLEVEL + 1 as SECONDLEVEL
from #BMST b
inner join results r
on r.CHILD = b.PARENT
and b.LEVEL > r.LEVEL
)
select *
from results
运算符。顶部是查询UNION ALL
表,它使用它来加入已经提取的结果的底部。
就是这样。你现在有递归。