27,579
社区成员
发帖
与我相关
我的任务
分享
--适用于 SQLServer2005+
USE tempdb
GO
IF OBJECT_ID('table1') IS NOT NULL DROP TABLE table1
IF OBJECT_ID('table2') IS NOT NULL DROP TABLE table2
create table table1(UserType nvarchar(1),UserName nvarchar(20),UserWant numeric(10,0),UserAct numeric(10,0))
insert into table1 values('A','小王',100,0);
insert into table1 values('A','老王',200,0);
insert into table1 values('A','小李',300,0);
insert into table1 values('B','大刘',155,0);
create table table2(UserType nvarchar(1),TotalAct numeric(10,0));
insert into table2 values('A',500);
insert into table2 values('B',100);
;WITH base AS(
SELECT ROW_NUMBER()OVER(PARTITION BY userType ORDER BY UserWant ASC) AS rid,* FROM table1
)
, cte AS(
SELECT *,(SELECT SUM(UserWant) FROM base AS b WHERE b.rid<=a.rid AND b.UserType=a.UserType) AS total
FROM base AS a
)
,cte2 AS(
SELECT *,(SELECT TOP 1 TotalAct FROM table2 AS b WHERE a.userType=b.UserType) AS ActTotal
FROM cte a
)
,cte3 AS (
SELECT UserType,UserName,UserWant,CASE WHEN ActTotal-total>=0 THEN UserWant ELSE UserWant-(Total-ActTotal) END AS UserAct FROM cte2
)
UPDATE table1
SET UserAct = b.UserAct
FROM cte3 AS b
WHERE table1.UserType=b.UserType AND table1.UserName=b.UserName
SELECT * FROM table1 AS t
/*
UserType UserName UserWant UserAct
-------- -------------------- --------------------------------------- ---------------------------------------
A 小王 100 100
A 老王 200 200
A 小李 300 200
B 大刘 155 100
*/
USE tempdb
GO
IF OBJECT_ID('table1') IS NOT NULL DROP TABLE table1
IF OBJECT_ID('table2') IS NOT NULL DROP TABLE table2
create table table1(UserType nvarchar(1),UserName nvarchar(20),UserWant numeric(10,0),UserAct numeric(10,0))
insert into table1 values('A','小王',100,0);
insert into table1 values('A','老王',200,0);
insert into table1 values('A','小李',300,0);
insert into table1 values('B','大刘',155,0);
create table table2(UserType nvarchar(1),TotalAct numeric(10,0));
insert into table2 values('A',500);
insert into table2 values('B',100);
;WITH cte AS(
SELECT *,sum(userwant) OVER (PARTITION BY userType ORDER BY UserWant ASC) AS total FROM table1 AS t
),cte2 AS(
SELECT *,(SELECT TOP 1 TotalAct FROM table2 AS b WHERE a.userType=b.UserType) AS ActTotal
FROM cte a
)
--SELECT * FROM cte2
,cte3 AS (
SELECT UserType,UserName,UserWant,CASE WHEN ActTotal-total>=0 THEN UserWant ELSE UserWant-(Total-ActTotal) END AS UserAct FROM cte2
)
UPDATE table1
SET UserAct = b.UserAct
FROM cte3 AS b
WHERE table1.UserType=b.UserType AND table1.UserName=b.UserName
SELECT * FROM table1 AS t
/*
UserType UserName UserWant UserAct
-------- -------------------- --------------------------------------- ---------------------------------------
A 小王 100 100
A 老王 200 200
A 小李 300 200
B 大刘 155 100
*/
create table table1(UserType nvarchar(1),UserName nvarchar(50),UserWant numeric(10,0),UserAct numeric(10,0))
insert into table1 values('A','小王',100,0);
insert into table1 values('A','老王',200,0);
insert into table1 values('A','小李',300,0);
insert into table1 values('A','小明',300,0);
insert into table1 values('B','大刘',155,0);
create table table2(UserType nvarchar(1),TotalAct numeric(10,0));
insert into table2 values('A',500);
insert into table2 values('B',100);
;WITH cte AS (
SELECT a.*,b.TotalAct,ROW_NUMBER() OVER(PARTITION BY a.UserType ORDER BY (SELECT 1)) AS rn
FROM table1 a
INNER JOIN table2 b ON a.UserType=b.UserType
),cte2 AS (
SELECT *,CAST((totalact-userwant) AS NUMERIC(10,0)) AS cnt FROM cte WHERE rn=1
UNION ALL
SELECT a.*,cast((b.cnt-a.userwant) AS NUMERIC(10,0) ) FROM cte a
INNER JOIN cte2 b ON a.usertype=b.usertype AND a.rn=b.rn+1
),cte3 AS (
SELECT usertype,username,userwant,CASE WHEN cnt>=0 THEN userwant ELSE userwant+cnt END AS useract
FROM cte2
),cte4 AS (
SELECT usertype,username,userwant,CASE WHEN useract>0 THEN useract ELSE 0 END AS useract
FROM cte3
)
UPDATE a SET a.useract=b.useract
FROM table1 a
INNER JOIN cte4 b ON a.UserType=b.usertype AND a.username=b.username
SELECT * FROM table1
ORDER BY usertype
-- 给 table1 加个自增列来确保顺序
alter table table1 add id int identity;
go
-- 更新
update a
set UserAct = case
when c.UserWant<=b.TotalAct then a.UserWant
else b.TotalAct - (c.UserWant-a.UserWant)
end
from table1 a, table2 b, (
select id, UserWant=sum(UserWant) over(partition by UserType order by id)
from table1
) c
where a.UserType = b.UserType and a.id = c.id
and c.UserWant - a.UserWant <= b.TotalAct
;
select * from table1