最近在做项目的时候遇到一个表,将省市区都放到一个表里存储,通过父ID字段来表示省市区的关系。

创建表语句

CREATE TABLE [dbo].[Table_6](
[id1] [int] NOT NULL,
[name] [varchar](50) NOT NULL,
[id2] [int] NOT NULL
) ON [PRIMARY]

插入数据

insert Table_6
select 1,'江苏',0 union all
select 2,'南京',1 union all
select 3,'杭州',4 union all
select 4,'浙江',0 union all
select 5,'白下',2 union all
select 6,'余杭',3

查询结果为

图1

期望的结果

图2

如果该记录的id2能够在表内找到,则将id2对应的记录的名称与当前记录的名称拼接在一起,如果其上层记录的id2不为0,就继续往上找,直到找到其id2为0为止。要找到图1中的父节点很简单,用下面的语句即可。

select * from [Table_6] A
inner join [Table_6] B
on A.id2=B.id1

得到的结果是

图3

这里如果我们仅取图3中的第一列,第五列和最后一列

图4

将图1和图4一起看,会发现现在已经取得了图1中的每个记录的父记录,并且id1都是第一层记录的ID。图4中只有第2和3条记录的id2不为0,也就是说其还有父记录,如果将图4的结果集再和图1关联一次,那么就得到了下面的结果

图5

将图1、图4和图5合并起来看,然后按id1分组,就会发现将每个组中的name拼接起来就是期望的图2的结果了。上述的方法对于有限级有用,但是如果是无限级拼接又该怎么办呢。

在SQL Server 2005中提供了公用表表达式(CTE),这个类似于表变量,但是比表变量效率高,通过它可以实现递归访问表的效果,例如要一次得到图1、图4和图5的结果

WITH cte AS
(
SELECT [level]=1,id1, name, id2 from [Table_6]
UNION ALL
SELECT [level]=[level]+1, A.id1, b.name, b.id2
FROM cte A
INNER JOIN [Table_6] B
ON A.id2 = B.id1
) select * from cte order by id1

得到的结果是:

最后如果要得到图2的结果,给出完整的SQL语句

WITH cte AS
(
SELECT [level]=1,id1, name, id2 from [Table_6]
UNION ALL
SELECT [level]=[level]+1, A.id1, b.name, b.id2
FROM cte A
INNER JOIN [Table_6] B
ON A.id2 = B.id1
)
SELECT A.id1, name = STUFF((SELECT '-'+name FROM cte B
WHERE b.id1=a.id1 ORDER BY [level] DESC FOR XML PATH('')),1,1,''), id2 = MAX(CASE WHEN [level]=1 THEN id2 END)
FROM cte A GROUP BY id1

SQL也能玩递归的更多相关文章

  1. 你真的会玩SQL吗?玩爆你的数据报表之存储过程编写(上)

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  2. 【吐血分享】SQL Server With As 递归获取层级关系数据

    纯洁的一周又开始了,今天看到一则新闻,笑尿了,和袁友们一起娱乐下 最近两月在做基于Saas模式的人力资源管理产品,平常数据库设计我经常会遇到如下需求场景: 以前商城类网站在设计类型表的时候,设计成单表 ...

  3. 在论坛中出现的比较难的sql问题:34(递归 获取连续值问题)

    原文:在论坛中出现的比较难的sql问题:34(递归 获取连续值问题) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  4. 在论坛中出现的比较难的sql问题:33(递归 连续日期问题 )

    原文:在论坛中出现的比较难的sql问题:33(递归 连续日期问题 ) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必 ...

  5. 在论坛中出现的比较难的sql问题:21(递归问题 检索某个节点下所有叶子节点)

    原文:在论坛中出现的比较难的sql问题:21(递归问题 检索某个节点下所有叶子节点) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. ...

  6. 在论坛中出现的比较难的sql问题:12(递归问题2 拆分字符串)

    原文:在论坛中出现的比较难的sql问题:12(递归问题2 拆分字符串) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有 ...

  7. 在论坛中出现的比较难的sql问题:8(递归问题 树形结构分组)

    原文:在论坛中出现的比较难的sql问题:8(递归问题 树形结构分组) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必 ...

  8. sql server 2000/2005递归

    /* 递归查询 塗聚文---SQL Server 2005环境下的实现: */--生成测试数据 create table Dept(ID int,ParentID int,msg varchar(20 ...

  9. 妙用CTE,一条语句实现sql递归查询,SQLServer 递归

    数据库设计中经常碰到父子节点的关系结构,经常需要找到某个节点的根,或者某个节点的所有子节点,一般做法都是在业务层做递归的方式实现,或者数据库存储过程实现.但其实SQLServer提供的CTE可以很好的 ...

随机推荐

  1. 如何让Windows程序只运行一个程序实例?

    要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...

  2. 复旦大学2016--2017学年第一学期高等代数I期末考试情况分析

    一.期末考试成绩班级前十名 宁盛臻(100).朱民哲(92).徐钰伦(86).范凌虎(85).沈伊南(84).何陶然(84).丁知愚(83).焦思邈(83).董瀚泽(82).钱信(81) 二.总成绩计 ...

  3. AES加解密【示例】

    代码 /**  * AES算法加密.JRE默认只能用16个字节(128)位密钥  */ public class AESUtils {     //使用指定转换的 Cipher 对象     publ ...

  4. jquery 关于event.target使用的几点说明介绍

    event.target说明:引发事件的DOM元素. this和event.target的区别js中事件是会冒泡的,所以this是可以变化的,但event.target不会变化,它永远是直接接受事件的 ...

  5. 推送消息实现icon角标的动态显示

    在你自己服务器上做计数,客户端做减法并反馈给你的服务器 ,然后你服务器将需要显示的数字发送给苹果推送服务器(就是消息中的badge)比如:1,你服务器上发送出去3个推送消息到A手机           ...

  6. VC++ 17、18课

    进程间通信的四种方式: 剪贴板 匿名管道 命名管道 邮槽 容器和服务器程序 容器应用程序是可以嵌入或链接对象的应用程序.word就是容器应用程序. 服务器应用程序是创建对象并且当对象呗双击时,可以被启 ...

  7. java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解(勿删)

    head first java里写到“java是通过值传递的,也就是通过拷贝传递”,由此得出结论,方法无法改变调用方传入的参数.该怎么理解呢? 看例子: public class Test1 { pu ...

  8. 常用css表达式-最小宽度-上下居中

    /* IE6下最小宽度的CSS表达式 */ width:100%; min-width:1024px; _width:expression((document.documentElement.clie ...

  9. python 中调用windows系统api操作剪贴版

    # -*- coding: utf-8 -*- ''' Created on 2013-11-26 @author: Chengshaoling ''' import win32clipboard a ...

  10. 【读书笔记】【CLR via C#】【第一章】The CLR’s Execution Model

    内容提要 本章的目的是对.Net 框架的设计做一个总体的介绍,包括介绍框架中使用的一些技术.定义一些术语.同时会展示从源代码生成应用程序(或者一些包含了一些自定义类型的可以发布的组件),并且会解释程序 ...