22,209
社区成员
发帖
与我相关
我的任务
分享
--第一次执行均摊
update T
set 实际付款=中标金额*1.0000/总中标金额*首付款
FROM(SELECT *,SUM(中标金额)OVER(PARTITION BY 总金额,首付款)[总中标金额] FROM 测试数据)T
--第二次执行将余数清除,确保等于总首付款
;WITH CTE AS(
SELECT *,ROW_NUMBER()OVER(PARTITION BY 总金额,首付款 ORDER BY GETDATE())RN FROM 测试数据
)
update T1
set 实际付款=T2.首付款-T2.[总实际付款]
FROM CTE T1 JOIN
(SELECT 总金额,首付款,SUM(实际付款)[总实际付款]
FROM CTE
WHERE RN>1
GROUP BY 总金额,首付款
)T2 ON T1.总金额=T2.总金额 AND T1.首付款=T2.首付款
WHERE T1.RN=1
WITH test(总金额,中标方,中标金额,首付款,实际付款) AS (
SELECT 90,'A',25,30,Convert(int,NULL) UNION ALL
SELECT 90,'B',50,30,NULL UNION ALL
SELECT 90,'C',15,30,NULL
)
SELECT * INTO #temp FROM test
UPDATE #temp
SET 实际付款 = ROUND(首付款*中标金额/总金额,0)
SELECT 中标方,实际付款 FROM #temp
UPDATE TOP(1) #temp
SET 实际付款 = 实际付款 + 首付款 - (SELECT SUM(实际付款) FROM #temp)
WHERE 实际付款 = (SELECT MAX(实际付款) FROM #temp)
SELECT 中标方,实际付款 FROM #temp
(3 行受影响)
中标方 实际付款
------ -----------
A 8
B 16
C 5
(3 行受影响)
(1 行受影响)
中标方 实际付款
------ -----------
A 8
B 17
C 5
(3 行受影响)
create table 测试数据
(总金额 int,
中标方 varchar(5),
中标金额 int,
首付款 int,
实际付款 decimal(18,4) -- 单位万,精确到元即为小数后4位.
)
insert into 测试数据
select 90,'A',25,30,null union all
select 90,'B',50,30,null union all
select 90,'C',15,30,null
-- 计算实际付款
update 测试数据
set 实际付款=中标金额*1.0000/总金额*首付款
-- 计算结果
select * from 测试数据
/*
总金额 中标方 中标金额 首付款 实际付款
----------- ----- ----------- ----------- ---------------------------------------
90 A 25 30 8.3333
90 B 50 30 16.6667
90 C 15 30 5.0000
(3 行受影响)
*/
-- 验证 三个和值是否等于首付款总数
select sum(实际付款) '首付款总数' from 测试数据
/*
首付款总数
---------------------------------------
30.0000
(1 行受影响)
*/
;WITH 合同表(合同ID,名称,总金额,首总付)AS(
SELECT 1,'合同',900000,300000
)
,中标情况表(合同ID,中标人,金额)AS(
SELECT 1,'A',250000
UNION ALL SELECT 1,'B',500000
UNION ALL SELECT 1,'C',150000
)
--以上假设你数据是长那样的
--以下开始查询
SELECT T2.中标人,ROUND(CAST(T2.金额 AS DECIMAL(19,6))/T1.总金额*T1.首总付,0)均摊首付款 FROM 合同表 T1
LEFT JOIN 中标情况表 T2 ON T1.合同ID=T2.合同ID