22,298
社区成员




--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([SPID] int,[Blocked] int)
Insert #T
select 157,106 union all
select 311,152 union all
select 262,154 union all
select 85,266 union all
select 106,266 union all
select 154,266 union all
select 340,266 union all
select 348,266 union all
select 175,311 union all
select 355,311 union all
select 391,311 union all
select 380,340 union all
select 152,348 union all
select 188,190
Go
--测试数据结束
SELECT DISTINCT
a.Blocked
FROM #T a
WHERE NOT EXISTS
(
SELECT * FROM #T b WHERE a.Blocked = b.SPID
);
USE tempdb
GO
IF OBJECT_ID('dbo.[t]') IS NOT NULL
DROP TABLE dbo.[t]
GO
CREATE TABLE dbo.[t](
[SPID] INT
,[Blocked] INT
)
GO
SET NOCOUNT ON
INSERT INTO dbo.[t] VALUES(N'157',N'106')
INSERT INTO dbo.[t] VALUES(N'311',N'152')
INSERT INTO dbo.[t] VALUES(N'262',N'154')
INSERT INTO dbo.[t] VALUES(N'85',N'266')
INSERT INTO dbo.[t] VALUES(N'106',N'266')
INSERT INTO dbo.[t] VALUES(N'154',N'266')
INSERT INTO dbo.[t] VALUES(N'340',N'266')
INSERT INTO dbo.[t] VALUES(N'348',N'266')
INSERT INTO dbo.[t] VALUES(N'175',N'311')
INSERT INTO dbo.[t] VALUES(N'355',N'311')
INSERT INTO dbo.[t] VALUES(N'391',N'311')
INSERT INTO dbo.[t] VALUES(N'380',N'340')
INSERT INTO dbo.[t] VALUES(N'152',N'348')
INSERT INTO dbo.[t] VALUES(N'188',N'190')
;WITH cte AS (
SELECT *
,CASE WHEN EXISTS(SELECT 1 FROM t AS b WHERE a.spid=b.blocked) THEN 1 ELSE 0 END AS [spidIsBlocked]
,CASE WHEN EXISTS(SELECT 1 FROM t AS b WHERE b.spid=a.blocked) THEN 1 ELSE 0 END AS [blockedBlockByOther]
FROM t AS a
)
--SELECT * FROM cte
SELECT spid
,MAX([type]) AS [level]
,(SELECT COUNT(1) FROM t WHERE t.blocked=tt.spid) AS blockedCnt
FROM (
SELECT spid,2 AS [type] FROM cte WHERE [spidIsBlocked]=1
UNION
SELECT blocked,2 AS [type] FROM cte WHERE [blockedBlockByOther]=1
UNION
SELECT blocked,1 AS [type] FROM cte
)
AS tt
GROUP BY spid
ORDER BY blockedCnt DESC,[level] DESC
/*
level = 2 的是比较严重的,自己与其它进程相互阻塞
level = 1 的只阻塞其它进程
blockedCnt 阻塞次数
*/
/*
spid level blockedCnt
----------- ----------- -----------
266 1 5
311 2 3
340 2 1
348 2 1
106 2 1
152 2 1
154 2 1
190 1 1
*/
--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([ParentID] int,[ChildID] int)
Insert #T
select 10,31 union all
select 31,81 union all
select 20,22 union all
select 30,50 union all
select 50,51 union all
select 55,58 union all
select 51,62 union all
select 62,90 union all
select 58,67
Go
--测试数据结束
DECLARE @sql VARCHAR(MAX)
SET @sql = ';WITH cte AS (
Select *,1 AS [level],parentid as oid from #T a WHERE NOT EXISTS(SELECT * FROM #T b WHERE a.ParentID=b.ChildID)
UNION ALL
SELECT #T.*,cte.level+1,oid FROM #T JOIN cte ON cte.ChildID = #T.ParentID
),ctea as (
SELECT * FROM cte
UNION ALL
SELECT t.ChildID,t.ChildID,t.level+1,t.oid FROM (SELECT *,ROW_NUMBER()OVER(PARTITION BY cte.oid ORDER BY cte.ChildID DESC) rn FROM cte)t WHERE rn=1
)
select oid'
;WITH cte AS (
Select *,1 AS [level],parentid as oid from #T a WHERE NOT EXISTS(SELECT * FROM #T b WHERE a.ParentID=b.ChildID)
UNION ALL
SELECT #T.*,cte.level+1,oid FROM #T JOIN cte ON cte.ChildID = #T.ParentID
),ctea as (
SELECT * FROM cte
UNION ALL
SELECT t.ChildID,t.ChildID,t.level+1,t.oid FROM (SELECT *,ROW_NUMBER()OVER(PARTITION BY cte.oid ORDER BY cte.ChildID DESC) rn FROM cte)t WHERE rn=1
)
SELECT @sql = @sql + ',max(case level when ''' + RTRIM(a.level)
+ ''' then ParentID else 0 end)[level' + RTRIM(a.level) + ']'
FROM ( SELECT DISTINCT
ctea.level
FROM ctea
) a
SET @sql = @sql
+ ' from ctea group by oid'
EXEC(@sql)