自连接查询

2024-01-11

是否可以仅使用 join 进行父子查询而不循环遍历临时表?

数据库样本:

menuid  name                parent  url
----------------------------------------------------------
A0000   Master              A0000   #
A0001   Rekening            A0000   /master/rekening.aspx
A0002   Master Nominal      A0001   /master/nominal.aspx
A0003   Master Satuan Other A0001   /master/satuan.aspx
A0004   Master Kondisi      A0000   /master/kondisi.aspx
A0005   Master Tujuan       A0003   /master/tujuan.aspx
A0006   Master Item         A0003   /master/item.aspx
A0007   Master Warehouse    A0000   /master/warehouse.aspx
A0008   Master Kapal        A0006   /master/kapal.aspx

选择想要的结果uri = '/master/kapal.aspx' :

menuid  name                parent  url
----------------------------------------------------------
A0000   Master              A0000   #
A0001   Rekening            A0000   /master/rekening.aspx
A0003   Master Satuan Other A0001   /master/satuan.aspx
A0006   Master Item         A0003   /master/item.aspx
A0008   Master Kapal        A0006   /master/kapal.aspx

选择想要的结果uri = /master/tujuan.aspx' :

menuid  name                parent  url
----------------------------------------------------------
A0000   Master              A0000   #
A0001   Rekening            A0000   /master/rekening.aspx
A0005   Master Tujuan       A0003   /master/tujuan.aspx

示例查询:

declare @menuid varchar(255) = 'menuid'
declare @parent varchar(255) = 'parent'
declare @temp_parent varchar(255)
declare @i smallint = 0

delete from temp_menu
while (@menuid <> @parent)
begin
  if(@i = 0) 
  begin
    insert into temp_menu
    select * from menu where uri = '/master/kapal.aspx'
    select @menuid = menuid, @parent = parent from menu where uri = '/master/kapal.aspx'
    set @i = 1;
    end
  else
  begin
    insert into temp_menu
    select * from menu where menuid = @parent
    select @menuid = menuid, @temp_parent = parent from menu where menuid = @parent
    set @parent = @temp_parent;
    end
end
select * from temp_menu

具有层次结构的示例:

A0000
|_______________________
|               |       |
A0001           A0004   A0007
|________
|       |
A0002   A0003
        |_______
        |       |
        A0005   A0006
                |
                A0008

更新 :我想从节点中获取最长分支的所有行parent to menuid并停止,如果parentmenuid或者没有menuid与 匹配parent.

添加脚本和示例

IF OBJECT_ID('dbo.menu', 'U') IS NOT NULL
  DROP TABLE dbo.menu
GO

IF OBJECT_ID('dbo.temp_menu', 'U') IS NOT NULL
  DROP TABLE dbo.temp_menu
GO

IF OBJECTPROPERTY(object_id('dbo.sp_get_parent'), N'IsProcedure') = 1
  DROP PROCEDURE dbo.sp_get_parent
GO

create table dbo.menu (
menuid varchar(255)
, name varchar(255)
, parent varchar(255)
, uri varchar(255)
);

insert into dbo.menu (menuid, name, parent, uri)
values ('A0000', 'Master', 'A0000', '#')
, ('A0001', 'Rekening', 'A0000', '/master/rekening.aspx')
, ('A0002', 'Master Nominal', 'A0001', '/master/nominal.aspx')
, ('A0003', 'Master Satuan Other', 'A0001', '/master/satuan.aspx')
, ('A0004', 'Master Kondisi', 'A0000', '/master/kondisi.aspx')
, ('A0005', 'Master Tujuan', 'A0003', '/master/tujuan.aspx')
, ('A0006', 'Master Item', 'A0003', '/master/item.aspx')
, ('A0007', 'Master Warehouse', 'A0000', '/master/warehouse.aspx')
, ('A0008', 'Master Kapal', 'A0006', '/master/kapal.aspx');

create table dbo.temp_menu (
menuid varchar(255)
, name varchar(255)
, parent varchar(255)
, uri varchar(255)
);

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

Create PROCEDURE [dbo].[sp_get_parent]
@uri VARCHAR (255)
AS

declare @menuid varchar(255) = 'menuid'
declare @parent varchar(255) = 'parent'
declare @temp_parent varchar(255)
declare @i smallint = 0

delete from temp_menu
while (@menuid <> @parent)
begin
  if(@i = 0) 
  begin
    insert into temp_menu
    select * from menu where uri = @uri
    select @menuid = menuid, @parent = parent from menu where uri = @uri
    set @i = 1;
  end
  else
  begin
    insert into temp_menu
    select * from menu where menuid = @parent
    select @menuid = menuid, @temp_parent = parent from menu where menuid = @parent
    set @parent = @temp_parent;
  end
end
select * from temp_menu order by menuid asc
GO

对于上面所需的示例可以尝试以下查询:

sp_get_parent '/master/kapal.aspx'

AND

sp_get_parent '/master/tujuan.aspx'

在 SQL Server 中,有关如何查询分层数据的每个问题的答案都是使用递归公用表表达式。

在您的情况下,由于您想要获得最长的分支,因此您应该添加一个计数列:

;WITH CTE AS
(
     SELECT menuid, name, parent, url, 0 as level
     FROM menu WHERE parent = menuid -- Usually, the parent column is simply nullable
     UNION ALL
     SELECT menu.menuid, menu.name, menu.parent, menu.url, level + 1
     FROM menu 
     INNER JOIN CTE ON menu.parent = CTE.menuid 
     AND menu.parent <> CTE.parent -- This is why parent column is nullable :-)
)

SELECT TOP 1 *
FROM CTE
ORDER BY Level DESC 

此查询将为您提供距其顶层父级最远的叶子。

Update
根据您的评论,我认为这就是您正在寻找的:

;WITH CTERecursion AS
(
     SELECT menuid, 
            name, 
            parent, 
            url, 
            0 as level,
            menuid as TopLevelParent
     FROM menu WHERE parent = menuid -- Usually, the parent column is simply nullable

     UNION ALL
     SELECT menu.menuid, 
            menu.name, 
            menu.parent, 
            menu.url, 
            level + 1,
            TopLevelParent
     FROM menu 
     INNER JOIN CTERecursion CTE ON menu.parent = CTE.menuid 
     AND menu.menuid <> CTE.menuid -- This is why parent column is nullable :-)

), CTELongestPath AS
(
    SELECT TOP 1 TopLevelParent
    FROM CTERecursion
    ORDER BY Level DESC 
)

SELECT menuid, name, parent, url
FROM CTERecursion r
INNER JOIN CTELongestPath l ON r.TopLevelParent = r.TopLevelParent

更新#2
现在你的问题改变了,你似乎只想从叶子遍历到顶层父级。在这种情况下,您的递归 CTE 应该是这样的:

DECLARE @url varchar(100) = '/master/kapal.aspx';

;WITH CTERecursion AS
(
     SELECT menuid, 
            name, 
            parent, 
            url
     FROM menu 
     WHERE url = @url

     UNION ALL
     SELECT menu.menuid, 
            menu.name, 
            menu.parent, 
            menu.url
     FROM menu 
     INNER JOIN CTERecursion CTE ON menu.menuid = CTE.parent
     AND menu.menuid <> CTE.menuid -- This is why parent column is nullable :-)
)

SELECT menuid, name, parent, url
FROM CTERecursion 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自连接查询 的相关文章

  • .net Framework 4.0 中地理 SQL Server 数据类型的 C# 等效项是什么?

    net web应用程序使用 net 4 0框架 我有一个存储过程 它接受 sql server 2008 R2 中的地理数据类型 我想将 C 代码中的数据插入 SQL Server 但我无法找到应在 C 中使用哪种与 SQL Server
  • LINQ to SQL:从位于不同服务器上的两个数据库获取记录

    我需要从两个不同的表中获取记录 数据库位于两个不同的 SQL Server 中 例如 销售数据库位于服务器 1 上 采购数据库位于服务器 2 上 销售和采购数据库都有一些表集 例如销售数据库中的 table1 和采购数据库中的 table2
  • 从 CTE 插入

    WITH DTL AS SELECT CMPI CODE CMN CDTY MTRL CMI WT FACTOR CMI CNTRCT RATE PL PRESENT PRICE TRM CODE ROUND NVL PRESENT PRI
  • 在 WHERE 子句中使用可选参数

    我有一个SP ALTER PROCEDURE dbo sp Compare lst varchar 100 frst varchar 100 NULL passportNo varchar 50 NULL AS SELECT FROM db
  • 如何使用 ALTER TABLE 添加新列并使其唯一?

    我该如何使用ALTER TABLE添加新列并使其独一无二 取决于 DBMS 但我认为以下内容相当可移植 ALTER TABLE table name ADD column name datatype ALTER TABLE table na
  • JbdcTemplate - 带有动态 SQL 查询的PreparedStatements

    I know jdbcTemplate可以用来创建PreparedStatements如果你这样设置 i e private JdbcTemplate jdbcTemplate String sqlQuery Select from tab
  • Wordnet sqlite 同义词和示例

    我正在尝试获取给定 wordid 的同义词和示例列表 经过大量的试验和错误 我可以获得所有同义词集的样本 但不是实际的同义词 这是我的查询 它给出了以下结果 select senses wordid senses synsetid sens
  • 如何在 SQL Server 2008 中使用 GUID 数据类型?

    我想使用建立一个员工表SQL SERVER 2008 在我的表中 我希望为每个员工提供一个 ID 我听说过GUID我有点明白它是一种数据类型 但我无法使用它 你能告诉我使用它的方法吗 顺便说一句 假设我想要这样的东西 CREATE TABL
  • PostgreSQL & regexp_split_to_array + 取消嵌套

    我有这样的绳子 测试1 纽约 X 测试 2 芝加哥 Y 测试 3 宾夕法尼亚州哈里斯堡 Z 我需要的结果是 Column1 Column 2 Column3 Test 1 new york X Test 2 chicago Y Test 3
  • MySQL解释更新

    作为我大学复习的一部分 我试图回答以下问题 至少在表的一个属性上创建索引 employees 数据库 您可以在其中使用 MySQL EXPLAIN 工具 清楚地显示好处 在条款或检索方面 和负面 在 更新条款 创建相关索引的信息 对于第一部
  • SQL查询获取最后两条记录的DateDiff

    我有一个名为 Event 的表 其中 eventNum 作为主键 日期作为 SQL Server 2008 R2 中的 datetime2 7 我试图获取表中最后两行的日期并以分钟为单位获取差异 这就是我目前所拥有的 Select DATE
  • 了解涉及 3 个或更多表时 JOIN 的工作原理。 [SQL]

    我想知道是否有人可以帮助我提高对 SQL 中 JOIN 的理解 如果它对问题很重要 我会特别考虑 MS SQL Server 取 3 个表 A B A 通过某些 A AId 与 B 相关 和 C B 通过某些 B BId 与 C 相关 如果
  • 使用显式值进行 BigQuery 合并

    据我所知 BigQuery 支持合并两个表 目前 INSERT操作允许将显式值插入表中 例如 INSERT dataset Inventory product quantity VALUES top load washer 10 front
  • 如何将此本机 SQL 查询转换为 HQL

    所以我有这个很长的复杂的 Native SQLQuery string hql SELECT FROM SELECT a rownum r FROM select f2 filmid f2 realisateurid f2 titre f2
  • 常量值如何影响连接的 ON 子句?

    我最近发现 LEFT JOIN 的 ON 子句可能包含 1 1 等值 这让我感到不安 因为它打破了我对连接功能的看法 我遇到过以下情况的更详细版本 SELECT DISTINCT Person ID FROM Person LEFT JOI
  • 从复选框列表中选择循环生成的复选框中的一个复选框

    抱歉我的英语不好 在我的 ASP NET 网站上 我从 SQL 表导入软件列表 看起来像这样 但实际上要长得多 Microsoft Application Error Reporting br br Microsoft Applicatio
  • 如何限制两个表之间一对多关系中的多个数量?

    我有一个带有两个 MySql 表的 MySQL 数据库 第一个是第一个表 表 A 有一列具有唯一值 从值 从 1 到 n 在第二个表 2 表 B 中 我有两列 在第一个表中我有一个名称 在第二个我的值从 1 到 n 如果我在 中添加一个值
  • sql脚本变量默认值

    我有一个脚本文件 例如测试 sql 我想从另一个脚本调用它 比如 caller sql 在 sqlcmd 模式下使用 r test sql 这工作正常 但我想在 test sql 中使用脚本变量 当我从 caller sql 调用 test
  • ActiveRecord 查询,按关联排序,最后一个 has_many

    我试图列出所有Users by the created at最近创建的关联记录 通讯 列 到目前为止我所拥有的 User includes communications order communications created at IS
  • SQL Server查询麻烦,多对多关系

    不知道如何用一行字来表达这个问题 对标题表示歉意 我的数据库中有3个表 例如 Shop Item 商店库存 Shop 和 Item 具有多对多关系 因此 ShopStock 表将它们链接起来 ShopStock 中的字段是 ID ShopI

随机推荐

  • 将轮廓路径转换为 ​​svg 路径

    我正在使用 openCV 和 python 从图像中提取轮廓 现在我需要将这些轮廓路径 列表 导出为 svg 路径 我怎样才能做到这一点 code ret thresh cv2 threshold imgray 27 25 0 contou
  • 如何生成“随机”但又“唯一”的数字?

    随机数是如何生成的 java等语言如何生成随机数 特别是GUID是如何生成的 我发现像伪随机数生成器这样的算法使用初始值 但我需要创建一个随机数程序 其中一旦出现的数字就永远不会重复 即使系统重新启动等也是如此 我认为我需要将这些值存储在任
  • 从 firebase 数据库检索数据到 textview 时如何创建换行符?

    我知道如果我想创建一个新行 我必须插入 n无论我需要在哪里创建该线 但我得到的是没有我在 firebase 数据库中已有的行的文本 有人可以告诉我如何解决这个问题吗 例如 如果我在数据库中有 hello n world 我明白了hello
  • jqGrid 自定义编辑对话框

    我正在开发一个使用 jqGrid 的应用程序 问题是在行编辑时出现的编辑对话框必须具有特定的布局 所以我更愿意通过ajax加载它 然后手动将数据发送回jqGrid 我在论坛上搜索了很多 但找不到如何执行此操作的示例 因此 我只需要 jqGr
  • 如何确定应用程序包中是否存在文件?

    抱歉 今天的第二个问题很愚蠢 是否可以确定应用程序包中是否包含文件 我可以毫无问题地访问文件 即 NSString pathAndFileName NSBundle mainBundle pathForResource fileName o
  • SQL ON DELETE CASCADE,删除以哪种方式发生?

    如果我在数据库中有两个关系 如下所示 CREATE TABLE Courses CourseID int NOT NULL PRIMARY KEY Course VARCHAR 63 NOT NULL UNIQUE Code CHAR 4
  • 在位图android上添加水效果

    如何在位图图像中添加水波 我在这里发现了触摸事件的水波纹效果 https github com esteewhy whater https github com esteewhy whater但无法在我的单个位图上实现 谁能帮忙在我的位图上
  • 使用 ExecuteSqlCommand() 创建触发器抛出“‘TRIGGER’一词附近的语法不正确。”

    这似乎是我遗漏了一个简单的细节 我只是不明白是什么 有了这个 string deleteTrigger IF OBJECT ID p0 IS NOT NULL DROP TRIGGER p1 string createTrigger CRE
  • 从响应头中删除服务器信息和 PHP 信息

    我怎样才能预防server info and php info显示在响应头中 对于服务器信息 在 apache2 conf 中添加以下行 ServerTokens ProductOnly ServerSignature Off 对于 PHP
  • SQL存储过程执行计划性能不佳——参数嗅探

    我有一个存储过程 它接受日期输入 如果没有传入值 则稍后将其设置为当前日期 CREATE PROCEDURE MyProc MyDate DATETIME NULL AS IF MyDate IS NULL SET MyDate CURRE
  • 在Excel中使用True、False、1、0作为VLOOKUP的最后一个值有什么区别?

    在Excel中 vlookup函数末尾有一个可选参数 称为 范围查找 或 not exact match 您可以为此值输入 1 0 true 或 false 它们之间有什么区别以及它是如何工作的 公式中的最后一个值有时称为Range Inp
  • 新 Xcode 项目中的 MainWindow.xib 在哪里?

    我使用 TabBar 模板在 Xcode 4 中启动了一个新项目 我注意到没有MainWindow xib项目中的文件 Apple 是否删除了该文件 如果没有这个文件 我如何访问主窗口 MainWindow xib 一开始有点多余 请记住它
  • 匿名类型的非只读替代方案

    在 C 中 匿名类型可以如下所示 method doStuff var myVar new a false b true if myVar a Do stuff 但是 以下内容将无法编译 method doStuff var myVar n
  • python unittest.TestCase.assertRaises 不起作用

    我正在尝试在 Python 中对 add 函数运行测试 但出现错误 7 E ERROR test upper main TestStringMethods Traceback most recent call last File C Use
  • 为什么我的 Silverlight 应用程序无法在 Internet Explorer 中加载?

    由于某些奇怪的原因 我的 Silverlight 4 应用程序未在 Internet Explorer 中加载 我没有看到任何错误消息 只是一个空白屏幕 它在 Chrome 中运行良好 有任何想法吗 当 SL 在浏览器中加载失败时 通常与
  • 如果未安装 access,我的程序仍然可以运行

    我正在开发一个程序 该程序从 Excel 文件检索信息并转换该信息以将其存储在 Access 数据库中并稍后使用 该程序将运行的计算机确实安装了Excel 但我不确定它是否有Access 我只是想知道我的程序在这种情况下是否可以工作 或者
  • 如何获取mongoDB中内部文档属性的值?

    我是 mongoDB 新手 我在网络应用程序中使用 mongoDB 我想知道如何获取文档的内部文档属性的值 可以说我的 JSON 是这样的 id oid 4ceb753a70fdf877ef5113ca Attrr1 value1 Attr
  • 使用 Core 图像过滤时出现内存泄漏

    所以我一直在使用核心图像在图像上应用滤镜 一切都很好 除了当我尝试一遍又一遍地应用相同的滤镜时 应用程序只是退出 我猜这是内存泄漏 这是代码 UIImage applyFilter UIImage picture UIImageOrient
  • 编写可扩展网站的技术

    我是网站可扩展性领域的新手 您能否向我建议一些使网站可扩展到大量用户的技术 在重负载下测试您的网站 监控所有统计数据 寻找瓶颈 修复瓶颈 返回1 祝你好运
  • 自连接查询

    是否可以仅使用 join 进行父子查询而不循环遍历临时表 数据库样本 menuid name parent url A0000 Master A0000 A0001 Rekening A0000 master rekening aspx A