有如下的 BOM 表,parent_part 与 child_part 是多对多的关系,现在要求查询出每个 child_part 的最顶层的 parent_part
CREATE TABLE pl_bom(
parent_part varchar(10),
child_part varchar(10))
INSERT INTO pl_bom
SELECT 'A','C' <place w:st="on"><span style="COLOR: blue">UNION</span></place> ALL
SELECT 'B','C' <place w:st="on"><span style="COLOR: blue">UNION</span></place> ALL
SELECT 'C','D' <place w:st="on"><span style="COLOR: blue">UNION</span></place> ALL
SELECT 'D','E' <place w:st="on"><span style="COLOR: blue">UNION</span></place> ALL
SELECT 'D','F' <place w:st="on"><span style="COLOR: blue">UNION</span></place> ALL
SELECT 'H','F'
即根据上述数据,应该得到如下结果
child_part parent_part
---------- -----------
C A
C B
D A
D B
E A
E B
F A
F B
F H
一般可能会考虑从 child_part 开始扫描的方法。但对于每个 child_part 而言,它有一至多个 parent_part,对于多个parent_part 而言,每个 parent_part 到最顶部的 parent_part 经过的层数还可能不一致,这会导致扫描算法不太好写,而且同一个 parent_part 如果被多个 child_part 引用的话, 还可能导致重复的搜索此 parent_part 的顶 parent_part。
下面的算法采用自 parent_part 反推 child_part 的方式,可以避免重复扫描某个 parent_part 到 child_part 的问题
-- 使用自顶向下展开
-- 因为要删除数据, 所以不能用原始表, 用个临时表
SELECT
id = IDENTITY(int, 1,1 ), child_part, parent_part
INTO #
FROM pl_bom
-- 从顶往下展
DECLARE @Level int
SET @Level = 1
SELECT
id = id * 1, Level = @Level,
child_part, parent_part
INTO #re
FROM # A
WHERE NOT EXISTS(
SELECT * FROM #
WHERE child_part = A.parent_part)
WHILE @@ROWCOUNT > 0
BEGIN
SET @Level = @Level + 1
DELETE A
FROM # A, #re B
WHERE A.id = B.id
AND B.Level = @Level - 1
INSERT #re(
id, Level,
child_part, parent_part)
SELECT
A.id, @Level,
A.child_part, B.parent_part
FROM # A, #re B
WHERE A.parent_part = B.child_part
AND B.Level = @Level - 1
END
-- 显示结果
SELECT
child_part, parent_part
FROM #re
ORDER BY 1, 2
-- 删除临时表
DROP TABLE #re, #
分享到:
相关推荐
Oracle存储过程中使用临时表 会话级临时表 事务级临时表
网上有人给出了佳的优化思路是: 1、先将大表中满足条件的记录抽出来生成一张临时表 2、再将这较小的临时表与另一张较小的表进行关联查询 先不论思路是否值得商榷,这把临时表当成... 关于临时表的使用至
SpringBoot 整合Mybatis 创建临时表
本资源结合实例实现一个复杂的存储过程,存储过程中有用到游标、临时表、循环、递归等知识,sql文件附有实例数据表创建的sql语句。
sqlserver 循环临时表插入数据到另一张表 -- 声明变量 DECLARE @SupCode as varchar(100), @ProdCode as varchar(50), @PackLayer as varchar(50), @CodeStatus as varchar(50), @ProductId as varchar(50), @...
Oracle 临时表功能介绍: Oracle中的临时表是全局的,需要在数据库设计时创建完成,而不是程序使用时。每个登陆用户都使用这一个相同的临时表,但互相之间看不到彼此的数据,也就是说临时表是会话独立的。
使用临时表空间组而非普通的临时表空间,有如下好处: 由于SQL查询可以并发使用几个临时表空间进行排序操作,因此SQL查询很少会出现排序空间超出,避免当临时表空间不足时所引起的磁盘排序问题。 可以在数据库级...
很好的,经典.创建Oracle 临时表,可以有两种类型的临时表:会话级的临时表,事务级的临时表 。
创建临时表。临时表与永久表相似,但临时表存储在 tempdb 中,当不再使用时会自动删除。
MS SQLSERVER,oracle 主流数据库中临时表的使用
也就是说当前临时表空间文件的大小是历史上使用临时表空间最大的大小。 临时表空间的主要作用: 索引create或rebuild Order by 或 group by Distinct 操作 Union 或 intersect 或 minus Sort-merge joins analyze
Oracle 临时表空间使用注意 Oracle 临时表空间使用注意 Oracle 临时表空间使用注意
1、局部临时表(#开头)只对当前连接有效,当前连接断开时自动删除。 2、全局临时表(##开头)对其它连接也有效,在当前连接和其他访问过它的连接都断开时自动删除。 3、不管局部临时表还是全局临时表,只要连接有...
SQL Server中关于临时表概念及创建和插入数据等问题 本地临时表 全局临时表 在程序中向临时表插入数据时报错……
oracle查找定位占用临时表空间较大的SQL语句方法,包括:(1)造成临时表空间暴涨的SQL还在运行中(2)造成临时表空间暴涨的SQL已经运行过了。
Oracle临时表空间的清理步骤,解决数据库临时表空间满的问题。
大家帮忙看看这个品牌维护的表单,在VFP中测试可以,一但连编就显示“不能更新临时表”。无论操作添加还是PAGE2的修改,我不知道是怎么回事,高手帮看看,谢谢!!!!表单和所用的表已上传
sqlserver中判断表或临时表是否存在
如果用户查询时,使用Order BY排序语句指定按员工编号来排序,那么排序后产生的所有记录就是临时数据。对于这些临时数据,Oracle数据库是如何处理的呢? 通 常情况下,Oracle数据库会先将这些临时数据存放到内存的...
外部临时表 通过CREATE TEMPORARY TABLE 创建的临时表,这种临时表称为...这种内部表对用户来说是不可见的,但是通过EXPLAIN或者SHOW STATUS可以查看MYSQL是否使用了内部临时表用来帮助完成某个操作。内部临时表在