所以假设我有一个桌子,bmst。我使用此查询查找结果集:
SELECT PARENT,
CHILD,
LEVEL,
QTY
FROM BMST
WHERE PARENT = '111'
结果集中是父零件号,以及儿童零件号,例如:
PARENT | CHILD | LEVEL | QTY
-----------------------------
111 | 222 | 0 | 2
111 | 333 | 0 | 1
111 | 444 | 0 | 1
该表提供了有关用于制作父零件的所有子零件的信息,以及每个父零件中使用的子零件的数量。级别的列的值为" 0",因为零件" 111"是我们关心的原点部分。我们不在乎" 111"部分是否是另一个较大父母部分的孩子。
如果儿童零件是由较小的儿童零件组成的,则可能是父零件。例如,此查询:
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
此新表中的级别值为'1'
进一步走," 222"部分的子部分本身可能会有子部分,因此" 777"部分的类似查询会返回:
PARENT | CHILD | LEVEL | QTY
-----------------------------
777 | 999 | 2 | 2
我的问题是,是否可以创建一个可以返回第一个结果集的查询,然后检查该结果集中的所有子零件值以查看这些零件是否有任何子零件,然后检查结果儿童零件的更多儿童零件等。直到不再有子零件,然后结合那些进入第一个结果的零件,因此看起来像:
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
级别值需要对查询进行更深入的每个步骤,最终结果集应显示进入请求的父部件的每个部分。
有没有办法在SQL中完成所有操作?还是我必须使用VB6或其他程序来通过循环迭代?所有反馈都将不胜感激。
而不是联合,您应该研究一个自我联接。您可以加入自己的表格,从而链接父母&子ID。它将需要一个条款来消除与自己一起加入的行。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
请注意,我发明了一些其他记录,以证明这涵盖了层次结构的所有级别。查询是不完美的,因为最上方的父级被排除(没有父级本身(,这可能是通过外部连接来解决的。
奇怪的是,此特定示例的结果密切模仿表本身,但这是在应用任何其他标准之前,例如您真正感兴趣的父元素。
这个问题可以提供更多信息:自加入的说明
做您想做的事,您需要一些称为递归的东西。当然,您可以按行分析IT(使用T-SQL或使用VB或您舒适使用的任何语言(,但是,使用称为Common Table Expressions
或CTE
的东西很容易解决此问题(递归(。
使用CTE
,您可以与您的结果相抵触,因此在这种情况下,孩子可以成为父母的亲子关系。
我创建了此脚本以向您展示如何。首先,我填充了一些临时表,之后我使用CTE
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 ()
的构造开始了。results
是一个虚构的名称,可以是任何东西。(在此示例中,我使用了新的COLOM 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
操作员。最高部分是查询#temp
表,它使用的是将其加入到已经被获取的结果的底部。
就是这样。您现在有递归。