日期:2014-05-18  浏览次数:20657 次

一个复杂的查询
数据库:SQL2000 +SP4

数据中有BH 和 SL 两个字段 SL 有正数有负数 要求相同BH的SL 正数、负数相抵 只显示正数不显示负数。
但是相同BH的数量合计不变
表结构如下
SQL code

CREATE TABLE #S
(BH VARCHAR(5) NULL,
 SL DECIMAL(8,2) NULL,
 XH INT IDENTITY
)

INSERT INTO #S
(BH,SL)
SELECT 'X01' AS BH,3 AS SL
UNION 
SELECT 'X01' AS BH,12 AS SL
UNION 
SELECT 'X01' AS BH,-2 AS SL
UNION 
SELECT 'X01' AS BH,-17 AS SL
UNION 
SELECT 'X01' AS BH,16 AS SL
UNION 
SELECT 'X02' AS BH,3 AS SL
UNION 
SELECT 'X02' AS BH,1 AS SL
UNION 
SELECT 'X02' AS BH,-2 AS SL
UNION 
SELECT 'X02' AS BH,-1 AS SL
UNION 
SELECT 'X02' AS BH,12 AS SL
UNION 
SELECT 'X03' AS BH,3 AS SL
UNION 
SELECT 'X03' AS BH,12 AS SL
UNION 
SELECT 'X03' AS BH,-2 AS SL
UNION 
SELECT 'X03' AS BH,-1 AS SL
UNION 
SELECT 'X03' AS BH,12 AS SL



要求结果

BH SL  
X01 3
X01 9
X02 1
X02 3
X02 9
X03 3
X03 9


------解决方案--------------------
-- SQL2000 
-- SQL2000 


 SELECT * ,IDENTITY(INT ,1,1 ) RN INTO #SS
 FROM ( SELECT BH,SL 
FROM #S A
WHERE NOT EXISTS ( SELECT *
FROM #S B
WHERE A.BH = B.BH
AND A.SL = 0 - B.SL )
AND A.SL > 0
UNION ALL 
SELECT DISTINCT BH, 0 
FROM #S A
WHERE NOT EXISTS ( SELECT *
FROM #S B
WHERE A.BH = B.BH
AND A.SL = 0 - B.SL )
AND A.SL > 0

)T 
ORDER BY BH ,SL 

SELECT BH,SL - (SELECT SUM(SL ) FROM #SS B WHERE A.BH = B.BH AND A.RN > B.RN ) SL FROM #SS A
WHERE A.SL >0
 IF OBJECT_ID ('tempdb..#SS') IS NOT NULL 
 DROP TABLE #SS 

-- SQL2005 以上
-- SQL2005 以上
;
WITH CTE
AS ( SELECT BH ,SL
FROM #S A
WHERE NOT EXISTS ( SELECT *
FROM #S B
WHERE A.BH = B.BH
AND A.SL = 0 - B.SL )
AND A.SL > 0),
CTE1
AS ( SELECT BH ,SL
FROM CTE
UNION ALL
SELECT DISTINCT BH ,0
FROM CTE ),
CTE2
AS ( SELECT ROW_NUMBER() OVER ( ORDER BY BH, SL ) RN ,
*
FROM CTE1)
SELECT BH ,
SL - ( SELECT SUM(SL)
FROM CTE2 B
WHERE A.BH = B.BH
AND A.RN > B.RN
) SL
FROM CTE2 A
WHERE SL > 0