有如下的 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, #
分享到:
相关推荐
在“无线路由器原理图+PCB+BOM.rar”这个压缩包中,包含了理解无线路由器工作原理、设计过程以及制造所需材料的关键信息。 1. **无线路由器原理**: 无线路由器主要由以下几个部分组成: - **处理器**:负责处理...
本篇文章将深入探讨如何在Oracle存储过程中使用临时表,包括会话级临时表和事务级临时表。 ### 会话级临时表 会话级临时表(Session-Level Temporary Tables)只在创建它的会话内可见,并且在会话结束时自动删除。...
以下是一个示例,展示如何在循环中动态创建临时表: ```sql DELIMITER // CREATE PROCEDURE procedure_name() BEGIN DECLARE cnt INT DEFAULT 0; DECLARE i INT DEFAULT 0; SET cnt = func_get_splitStringTotal...
这里我们使用Mybatis的注解来定义SQL语句,`@Insert`用于创建临时表,`@Select`用于查询临时表中的数据。注意,临时表在会话结束时会被自动删除,所以它们只对当前连接可见。 接着,我们需要创建一个对应的实体类`...
主流数据库中临时表的使用 在主流数据库中,临时表是一种特殊类型的表,它们是临时存储数据的容器。临时表可以在不同的数据库管理系统中使用,本文将对 MS SQLSERVER、Oracle 和 DB2 中的临时表进行介绍。 MS SQL ...
sqlserver 循环临时表插入数据到另一张表 -- 声明变量 DECLARE @SupCode as varchar(100), @ProdCode as varchar(50), @PackLayer as varchar(50), @CodeStatus as varchar(50), @ProductId as varchar(50), @...
网上有人给出了佳的优化思路是: 1、先将大表中满足条件的记录抽出来生成一张临时表 2、再将这较小的临时表与另一张较小的表进行关联查询 先不论思路是否值得商榷,这把临时表当成... 关于临时表的使用至
Oracle中的临时表是一种特殊的数据结构,用于存储会话或事务期间的数据,这些数据仅对当前会话可见,并在特定条件下...在使用临时表时,应考虑其生命周期、数据隔离性和性能影响,确保符合应用程序的需求和性能优化。
下面通过具体的SQL语句展示会话级临时表和事务级临时表的使用。 ##### 6.1 会话级临时表示例 ```sql CREATE GLOBAL TEMPORARY TABLE emp_temp_preserve ON COMMIT PRESERVE ROWS AS SELECT * FROM emp WHERE 1 = 2...
### 存储过程中的临时表使用方法 #### 一、临时表的概念与特点 临时表是一种特殊类型的数据库表,主要用于存储中间数据或辅助查询过程,它们通常存储在`tempdb`系统数据库中,并且在使用完毕后会被自动删除。根据...
解决 Oracle 临时表空间满的问题需要通过查看当前数据库的默认临时表空间、查看当前临时表空间的大小、创建新的临时表空间、将新建的临时表空间设置为数据库的默认临时表空间、删除原来的临时表空间、创建新的临时表...
本资源结合实例实现一个复杂的存储过程,存储过程中有用到游标、临时表、循环、递归等知识,sql文件附有实例数据表创建的sql语句。
在创建临时表时,可以使用 ON COMMIT DELETE ROWS 关键字来说明该表是事务性的临时表,而不是会话性质的临时表。例如: ```sql Create global temporary table Temp_user (ID NUMBER(12) Primary key, name varchar...
4. 使用 shell 脚本来记录和分析临时表空间使用情况:可以编写 shell 脚本来记录使用临时表空间的 SQL 语句,并将其保存在特定表中。 5. SQL 语句优化:通过优化 SQL 语句,可以减少临时表空间的使用量,从而解决...
2. **临时表的使用**:查询时,利用临时表来递归地获取各个层级的信息,实现无限级的BOM展示。 3. **临时表的清理**:查询完成后,删除临时表以释放资源。 #### 知识点四:使用VB.NET调用SQL Server进行BOM查询 在...
临时表是一种特殊的表,用于存储在单个查询或一系列查询中使用的数据,并且在不再需要时可以轻松地删除这些数据。根据其作用范围的不同,临时表分为两种类型:局部临时表和全局临时表。 1. **局部临时表**:这种...
临时表分为两种类型:本地临时表(Local Temporary Tables)和全局临时表(Global Temporary Tables),它们都有独特的特性和使用场景。 1. **本地临时表(#开头)** - 本地临时表的名称以单个井号 (#) 开头,如 `...
Oracle 临时表用法 Oracle 临时表是一种特殊的表结构,它可以在数据库中临时存储...但是,使用临时表时需要注意一些问题,例如避免在存储过程中创建临时表,避免在运行时创建临时表,以免导致数据库中的表数量增加。
【创建和使用临时表】 临时表在SQL Server中是一种非常实用的数据存储结构,它用于临时存储数据,适用于处理大量中间结果或执行复杂操作时。临时表分为两种类型:局部临时表(以单个井号“#”开头)和全局临时表...
临时表的一个应用示例是使用WHILE循环和DECLARE语句处理数据: ```sql Declare @Wokno Varchar(500) Declare @Str NVarchar(4000) Declare @Count int Declare @i int Set @i = 0 Select @Count = Count...