22,300
社区成员




CREATE TABLE TEMP_01(ID NVARCHAR(10),DAT NVARCHAR(10),Qty DECIMAL(22,2))
INSERT INTO TEMP_01
SELECT '100101','2013/07/18',700.00
UNION ALL
SELECT '100101','2013/07/19',800.00
UNION ALL
SELECT '100101','2013/07/24',813.00
UNION ALL
SELECT '100101','2013/07/25',10000.00
UNION ALL
SELECT '100101','2013/07/28',19743.00
UNION ALL
SELECT '100101','2013/07/30',9300.00
UNION ALL
SELECT '100102','2013/07/18',700.00
UNION ALL
SELECT '100102','2013/07/19',800.00
UNION ALL
SELECT '100102','2013/07/25',10000.00
UNION ALL
SELECT '100102','2013/07/30',9300.00
CREATE TABLE TEMP_02(ID NVARCHAR(10),Qty DECIMAL(22,2))
INSERT INTO TEMP_02
SELECT '100101',24610.00
UNION ALL
SELECT '100101',24610.00
IF OBJECT_ID('tempdb..#TEMP_01') IS NOT NULL DROP TABLE #TEMP_01
go
IF OBJECT_ID('tempdb..#TEMP_02') IS NOT NULL DROP TABLE #TEMP_02
go
CREATE TABLE #TEMP_01(ID NVARCHAR(10),DAT NVARCHAR(10),Qty DECIMAL(22,2))
INSERT INTO #TEMP_01
SELECT '100101','2013/07/18',700.00
UNION ALL
SELECT '100101','2013/07/19',800.00
UNION ALL
SELECT '100101','2013/07/24',813.00
UNION ALL
SELECT '100101','2013/07/25',10000.00
UNION ALL
SELECT '100101','2013/07/28',19743.00
UNION ALL
SELECT '100101','2013/07/30',9300.00
UNION ALL
SELECT '100102','2013/07/18',700.00
UNION ALL
SELECT '100102','2013/07/19',800.00
UNION ALL
SELECT '100102','2013/07/25',10000.00
UNION ALL
SELECT '100102','2013/07/30',9300.00
UNION ALL
SELECT '100103','2013/07/30',24600.00
CREATE TABLE #TEMP_02(ID NVARCHAR(10),Qty DECIMAL(22,2))
INSERT INTO #TEMP_02
SELECT '100101',24610.00
UNION ALL
SELECT '100102',24610.00
UNION ALL
SELECT '100103',24610.00
;WITH cte AS
(
SELECT *,
sumQty=(SELECT SUM(qty) FROM #TEMP_01 b WHERE b.id=a.id AND b.dat<=a.dat),
total = (SELECT TOP(1) qty FROM #TEMP_02 b WHERE b.id = a.id),
rowid = ROW_NUMBER() OVER(PARTITION BY a.id ORDER BY Dat)
FROM #TEMP_01 a
),
cte1 AS
(
SELECT *,diff=total-sumQty FROM cte
)
SELECT
id, dat, qty, newqty=(CASE WHEN diff>0 THEN Qty WHEN (NOT EXISTS(SELECT 1 FROM CTE1 m WHERE m.id=N.id AND m.dat<n.dat AND m.diff<0)) THEN Qty+diff ELSE 0 end)
FROM cte1 N
UNION ALL
SELECT c.* FROM
(
SELECT DISTINCT X.ID
FROM cte1 X
WHERE NOT EXISTS
(
SELECT 1 FROM cte1 Y
WHERE y.id = x.id
AND diff < 0
)
) B
CROSS APPLY
(
SELECT TOP(1) id, dat=CONVERT(CHAR(10),GETDATE(),111), Qty=-diff, neweQty=diff
FROM cte1 z
WHERE z.id = B.id
ORDER BY z.rowid DESC
) c
ORDER BY id, dat
/*
id dat qty newqty
100101 2013/07/18 700.00 700.00
100101 2013/07/19 800.00 800.00
100101 2013/07/24 813.00 813.00
100101 2013/07/25 10000.00 10000.00
100101 2013/07/28 19743.00 12297.00
100101 2013/07/30 9300.00 0.00
100102 2013/07/18 700.00 700.00
100102 2013/07/19 800.00 800.00
100102 2013/07/25 10000.00 10000.00
100102 2013/07/30 9300.00 9300.00
100102 2013/08/16 -3810.00 3810.00
100103 2013/07/30 24600.00 24600.00
100103 2013/08/16 -10.00 10.00
*/
IF OBJECT_ID('tempdb..#TEMP_01') IS NOT NULL DROP TABLE #TEMP_01
go
IF OBJECT_ID('tempdb..#TEMP_02') IS NOT NULL DROP TABLE #TEMP_02
go
CREATE TABLE #TEMP_01(ID NVARCHAR(10),DAT NVARCHAR(10),Qty DECIMAL(22,2))
INSERT INTO #TEMP_01
SELECT '100101','2013/07/18',700.00
UNION ALL
SELECT '100101','2013/07/19',800.00
UNION ALL
SELECT '100101','2013/07/24',813.00
UNION ALL
SELECT '100101','2013/07/25',10000.00
UNION ALL
SELECT '100101','2013/07/28',19743.00
UNION ALL
SELECT '100101','2013/07/30',9300.00
UNION ALL
SELECT '100102','2013/07/18',700.00
UNION ALL
SELECT '100102','2013/07/19',800.00
UNION ALL
SELECT '100102','2013/07/25',10000.00
UNION ALL
SELECT '100102','2013/07/30',9300.00
CREATE TABLE #TEMP_02(ID NVARCHAR(10),Qty DECIMAL(22,2))
INSERT INTO #TEMP_02
SELECT '100101',24610.00
UNION ALL
SELECT '100102',24610.00
;WITH cte AS
(
SELECT *,
sumQty=(SELECT SUM(qty) FROM #TEMP_01 b WHERE b.id=a.id AND b.dat<=a.dat),
total = (SELECT TOP(1) qty FROM #TEMP_02 b WHERE b.id = a.id),
rowid = ROW_NUMBER() OVER(PARTITION BY a.id ORDER BY Dat)
FROM #TEMP_01 a
),
cte1 AS
(
SELECT *,diff=total-sumQty FROM cte
)
SELECT
id, dat, qty, newqty=(CASE WHEN diff>0 THEN Qty WHEN (NOT EXISTS(SELECT 1 FROM CTE1 m WHERE m.id=N.id AND m.dat<n.dat AND m.diff<0)) THEN Qty+diff ELSE 0 end)
FROM cte1 N
UNION ALL
SELECT * FROM
(
SELECT TOP(1) id, dat=CONVERT(CHAR(10),GETDATE(),111), Qty=-diff, neweQty=diff
FROM cte1 X
WHERE NOT EXISTS
(
SELECT 1 FROM cte1 Y
WHERE y.id = x.id
AND diff < 0
)
ORDER BY X.rowid DESC
) B
ORDER BY id, dat
/*
id dat qty newqty
100101 2013/07/18 700.00 700.00
100101 2013/07/19 800.00 800.00
100101 2013/07/24 813.00 813.00
100101 2013/07/25 10000.00 10000.00
100101 2013/07/28 19743.00 12297.00
100101 2013/07/30 9300.00 0.00
100102 2013/07/18 700.00 700.00
100102 2013/07/19 800.00 800.00
100102 2013/07/25 10000.00 10000.00
100102 2013/07/30 9300.00 9300.00
100102 2013/08/16 -3810.00 3810.00
*/