22,294
社区成员
发帖
与我相关
我的任务
分享--> 生成测试数据: @tb
DECLARE @tb TABLE (A1 int,A2 int,A3 int,A4 int)
INSERT INTO @tb
SELECT 1,0,1,1 UNION ALL
SELECT 0,1,0,1 UNION ALL
SELECT 1,0,0,0
--SQL查询如下:
DECLARE @x xml;
SET @x = (SELECT * FROM @tb FOR XML PATH,TYPE);
CREATE TABLE #Tmp1(localname nvarchar(128),val int,rowid int,classid int);
INSERT #Tmp1
SELECT *,
classid=ROW_NUMBER()
OVER(PARTITION BY rowid
ORDER BY CAST(RIGHT(localname,PATINDEX('%[^0-9]%',
REVERSE(localname))-1)
AS int))
FROM (
SELECT T.x.value('local-name(.)','nvarchar(128)') AS localname,
T.x.value('.','int') AS val,
T.x.value('for $i in .
return count($i/../../*[.<<$i/..])+1','int') AS rowid
FROM @x.nodes('//row/*') AS T(x)
) AS A ;
CREATE TABLE #Tmp2(localname nvarchar(128),val int,
rowid int,classid int,total int,
path nvarchar(MAX),flag int);
;WITH Liang AS
(
SELECT *,total=val,path=CAST(localname AS nvarchar(MAX)),
flag = classid
FROM #Tmp1
UNION ALL
SELECT A.*,B.total+A.val,CAST(B.path + A.localname AS nvarchar(MAX)),
flag = A.classid
FROM #Tmp1 AS A
JOIN Liang AS B
ON A.rowid=B.rowid AND A.classid > B.classid
)
INSERT #Tmp2 SELECT * FROM Liang;
DECLARE @columns nvarchar(MAX),@avg_Columns nvarchar(MAX);
SELECT @columns = N'',@avg_Columns=N'';
SELECT @columns = @columns + ',MAX(CASE WHEN path = '''+path+''''
+' AND total > 0 THEN 1 ELSE 0 END) AS ['+path+']',
@avg_Columns = @avg_Columns + ',CAST(SUM(CASE WHEN path = '''+path+''''
+' AND total > 0 THEN 1 ELSE 0 END)*1.
/COUNT(CASE WHEN path = '''+path
+''' THEN 1 END) AS numeric(10,2))'
FROM #Tmp2 GROUP BY path;
SELECT @columns = STUFF(@columns,1,1,''),@avg_Columns=STUFF(@avg_Columns,1,1,'');
EXEC('SELECT '+@columns+' FROM #Tmp2 GROUP BY rowid
UNION ALL
SELECT '+@avg_Columns +' FROM #Tmp2')
GO
DROP TABLE #Tmp1,#Tmp2;
/*
A1 A1A2 A1A2A3 A1A2A3A4 A1A2A4 A1A3 A1A3A4 A1A4 A2 A2A3 A2A3A4 A2A4 A3 A3A4 A4
--------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 0.00 1.00 1.00 1.00 1.00 1.00 1.00
0.00 1.00 1.00 1.00 1.00 0.00 1.00 1.00 1.00 1.00 1.00 1.00 0.00 1.00 1.00
1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.67 1.00 1.00 1.00 1.00 0.67 1.00 1.00 0.33 0.67 0.67 0.67 0.33 0.67 0.67
(4 行受影响)
*/
