表自己与自己连接的问题,麻烦帮忙写个sql

todaytomorrow 2017-11-15 12:50:03
会议名称 会议时间 上届会议名称
会议0 2014.1.1 无
会议1 2015.1.1 会议0
会议2 2016.1.1 会议1
会议3 2017.1.1 会议2
会议A 2016.1.1 无
会议B 2017.1.1 会议A

要求输出
与会议2关联的所有会议
会议0 2014.1.1 无
会议1 2015.1.1 会议0
会议2 2016.1.1 会议1
会议3 2017.1.1 会议2

如果过于复杂,可以只输出会议2历届会议
会议0 2014.1.1 无
会议1 2015.1.1 会议0
会议2 2016.1.1 会议1


劳驾各位了。
...全文
259 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
道素 2017-11-16
  • 打赏
  • 举报
回复
下面写法和楼上差不多,第一步是向上找到第一次会议 然后再第一次为起点向下找,这个适用于你同时想把表亲也找出来的场合(比如本例的会议11,会议111非直系)

IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t
GO
CREATE TABLE #t(meeting nvarchar(20),meeting_time datetime,last_meeting nvarchar(20))
GO
INSERT INTO #t
 SELECT '会议0','2014.1.1','无' 
 UNION SELECT '会议1','2015.1.1','会议0' 
 UNION SELECT '会议2','2016.1.1','会议1' 
 UNION SELECT '会议11','2016.1.2','会议1' 
 UNION SELECT '会议111','2016.1.3','会议11' 
 UNION SELECT '会议3','2017.1.1','会议2' 
 UNION SELECT '会议A','2016.1.1','无' 
 UNION SELECT '会议B','2017.1.1','会议A' 
 
;WITH cte AS (
SELECT *,0 as lvl FROM #t WHERE meeting=N'会议2'
UNION ALL
SELECT t.*,lvl+1 as lvl FROM #t as t INNER JOIN cte ON t.meeting=cte.last_meeting
)
,cte2 AS (
SELECT top 1 * FROM cte order by lvl desc
UNION ALL
SELECT t.*,0 as lvl FROM #t as t INNER JOIN cte2 ON t.last_meeting=cte2.meeting
)
--SELECT top 1 * FROM cte order by lvl desc
SELECT * FROM cte2


+---------+-------------------------+--------------+-----+
| meeting | meeting_time            | last_meeting | lvl |
+---------+-------------------------+--------------+-----+
| 会议0     | 2014-01-01 00:00:00:000 | 无            | 2   |
| 会议1     | 2015-01-01 00:00:00:000 | 会议0          | 0   |
| 会议11    | 2016-01-02 00:00:00:000 | 会议1          | 0   |
| 会议2     | 2016-01-01 00:00:00:000 | 会议1          | 0   |
| 会议3     | 2017-01-01 00:00:00:000 | 会议2          | 0   |
| 会议111   | 2016-01-03 00:00:00:000 | 会议11         | 0   |
+---------+-------------------------+--------------+-----+
顺势而为1 2017-11-15
  • 打赏
  • 举报
回复
就是以会议2作为父件号进行递降归查询就可以了
RINK_1 2017-11-15
  • 打赏
  • 举报
回复

 with cte
 as
 (select *,0 as level from table 
  where 会议名称='会议2'
  union all
  select A.*,B.level+1 from t A
  join cte B ON A.会议名称=B.上届会议名称
  where B.level>=0
  union all
  select A.*,C.level-1 from table A
  join cte C on A.上届会议名称=C.会议名称
  where C.level<=0)
  
select * from cte order by level desc
听雨停了 2017-11-15
  • 打赏
  • 举报
回复

use Tempdb
go
--> --> 听雨停了-->测试数据
 
if not object_id(N'Tempdb..#tab') is null
	drop table #tab
Go
Create table #tab([会议名称] nvarchar(23),[会议时间] Date,[上届会议名称] nvarchar(23))
Insert #tab
select N'会议0','2014.1.1',N'无' union all
select N'会议1','2015.1.1',N'会议0' union all
select N'会议2','2016.1.1',N'会议1' union all
select N'会议3','2017.1.1',N'会议2' union all
select N'会议A','2016.1.1',N'无' union all
select N'会议B','2017.1.1',N'会议A'
--测试数据结束

WITH cte AS (
SELECT * FROM #tab WHERE 上届会议名称='会议2'
UNION ALL
SELECT a.* FROM #tab A
INNER JOIN cte b ON a.会议名称=b.上届会议名称
)
SELECT * FROM cte
ORDER BY 会议名称

会议名称                    会议时间       上届会议名称
----------------------- ---------- -----------------------
会议0                     2014-01-01 无
会议1                     2015-01-01 会议0
会议2                     2016-01-01 会议1
会议3                     2017-01-01 会议2

吉普赛的歌 版主 2017-11-15
  • 打赏
  • 举报
回复
USE tempdb
GO
IF OBJECT_ID('t') IS NOT NULL DROP TABLE t
GO
CREATE TABLE t([会议名称] nvarchar(20),[会议时间] datetime,[上届会议名称] nvarchar(20))
GO
INSERT INTO t
 SELECT '会议0','2014.1.1','无' 
 UNION SELECT '会议1','2015.1.1','会议0' 
 UNION SELECT '会议2','2016.1.1','会议1' 
 UNION SELECT '会议3','2017.1.1','会议2' 
 UNION SELECT '会议A','2016.1.1','无' 
 UNION SELECT '会议B','2017.1.1','会议A' 

;WITH cte AS (
SELECT * FROM t WHERE [会议名称]=N'会议2'
UNION ALL
SELECT t.* FROM t INNER JOIN cte ON t.[会议名称]=cte.[上届会议名称]
)
,cte2 AS (
SELECT * FROM t WHERE [会议名称]=N'会议2'
UNION ALL
SELECT t.* FROM t INNER JOIN cte2 ON t.[上届会议名称]=cte2.[会议名称]
)
SELECT * FROM cte
UNION 
SELECT * FROM cte2 ORDER BY [会议名称]
/*
会议名称                 会议时间                    上届会议名称
-------------------- ----------------------- --------------------
会议0                  2014-01-01 00:00:00.000 无
会议1                  2015-01-01 00:00:00.000 会议0
会议2                  2016-01-01 00:00:00.000 会议1
会议3                  2017-01-01 00:00:00.000 会议2
*/
SQLUtility - SQLServer 工具箱 软件说明:   在使用SQLServer企业管理器生成SQL脚本时,并没有按照数据库对象的依赖关系对脚本顺序进行排序。这个BUG导致了生成的脚本无法直接执行,开发人员必须手工对其进行排序或者寻找其他替代方案,从而增加了很大的工作量和麻烦。写本工具的初始原因就是为了解决上述问题,既然写好了,就应该和大家共享。在发布之前顺便又添加了清除事务日志的功能,以后有时间、有需要的话,打算添加更多的实用功能。希望这个小工具能给大家带来一些帮助。 运行环境:   由于是使用.NET写的,所以运行前需要安装.NET运行环境,这可能会给您带来一些麻烦(下载和安装运行环境),在此,我对所有受到影响的朋友示歉意! 本工具支持SQLServer2000+sp2以上版本,希望大家帮忙测试、报告BUG或提出建议,欢迎到我的BLOG来讨论,谢谢! 运行环境下载地址(23M): http://www.microsoft.com/downloads/details.aspx?FamilyId=262D25E3-F589-4842-8157-034D1E7CF3A3&displaylang=en http://www.ustc9703.com/download/get.asp?id=21&type=1&url=1 http://cq.down.chinaz.com/down/NETFramework.exe 如何选择和连接数据库: • 先从下拉框中选择服务器 • 如果使用用户名和密码登录,则填入用户名和密码(不要选择“集成Windows认证”复选框) • 如果使用Windows认证登录,则选中“集成Windows认证”复选框 • 完成上述步骤后,就可以从下拉框中选择数据库了(您也可以点击“重新连接”以刷新数据库信息) • 选择好数据库后,就可以执行以下各项功能 SQL脚本排序: • 使用前请先在SQLServer企业管理器里生成SQL脚本,保存为文件 • 运行本程序,在主界面上选择数据库,点击“脚本排序”按钮进入排序界面 • 在脚本排序界面点“浏览”按钮选择刚才生成的文件,点击“开始排序”按钮 清除事务日志: • 运行本程序,在主界面上选择数据库,点击“清除日志”按钮 数据导出: • 运行本程序,在主界面上选择数据库,点击“数据导出”按钮进入数据导出界面 • 导出XML:在数据导出界面中选择要导出的数据,点击“导出XML”按钮,选择要保存的文件后等待导出结束即可;导出的结果是XML文件,该文件可以用“数据导入”功能导入到目标数据库。 • 导出SQL:在数据导出界面中选择要导出的数据,点击“导出SQL”按钮,选择要保存的文件后等待导出结束即可;导出的结果是SQL脚本,该脚本可以用查询分析器执行。 数据导入: • 运行本程序,在主界面上选择数据库,点击“数据导入”按钮进入数据导入界面 • 进入界面时会要求您选择数据文件,您也可以点击“打开XML数据文件”选择其他的数据文件 • 在数据导入界面中选择要导入的数据,点击“数据检测”按钮可以检查目标数据库中是否有已存在的数据 • 在数据导入界面中选择要导入的数据,点击“导入数据”按钮可以将所选数据导入到目标数据库 • 说明:导入过程中会自动处理Identity列,并且会根据之间的依赖关系,先导入主键再导入外键 作者联系方式: Email : xian@vip.163.com Blog : http://www.cnblogs.com/happyprogram/

34,591

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧