我有一张桌子
staff Type col1 col2
1 a 0 200
1 b 50 2000
1 c 2 200
2 a 0 100
2 b 25 1000
2 c 2 200
3 a 0 150
3 b 35 1500
3 c 2 200
我只是想知道我是否可以根据每位员工col1
列中的值更新col2
和Type
。我的更新逻辑将是例如员工1
更新col1
,其中Type
= a是200 /(2000/50)= 5
更新col1
,其中Type
= b为col1
- (200 /(2000/50))= 50-5 = 45
更新col2
,其中Type
= b是2000-200 = 1800
更新col2
,其中Type
= a到0
请查看我需要达到的结果如下:更新值(*)
staff Type col1 col2
1 a 5* 0*
1 b 45* 1800*
1 c 2 200
2 a 2.5* 0*
2 b 22.5* 900*
2 c 2 200
3 a 3.5* 0*
3 b 31.5* 1350*
3 c 2 200
是否可以在不使用游标/循环/函数/ ctes的情况下完成此操作?
答案 0 :(得分:0)
尝试以下代码
DECLARE @myTable TABLE (
staff INTEGER NOT NULL
,Type VARCHAR(1) NOT NULL
,col1 INTEGER NOT NULL
,col2 INTEGER NOT NULL
)
INSERT INTO @myTable VALUES(1,'a',0,200),
(1,'b',50,2000),
(1,'c',2,200),
(2,'a',0,100),
(2,'b',25,1000),
(2,'c',2,200),
(3,'a',0,150),
(3,'b',35,1500),
(3,'c',2,200)
UPDATE t1
SET Col1 = CASE WHEN Type ='a'
THEN col2/(Select Col2/Col1 FROM @myTable T2 WHERE T2.Type = 'b' AND T2.staff = T1.Staff)
WHEN Type ='b'
THEN col1 - ((Select Col2 FROM @myTable T2 WHERE T2.Type = 'a' AND T2.staff = T1.Staff)/(Col2/Col1))
ELSE COl1
END ,
Col2 = CASE WHEN Type = 'b'
THEN Col2 - (Select Col2 FROM @myTable T2 WHERE T2.Type = 'a' AND T2.staff = T1.Staff)
WHEN Type = 'a'
THEN 0
Else Col2
END
FROM @MyTable t1
SELECT * FROM @myTable
答案 1 :(得分:0)
你可以在一个大规模的查询中完成它,但是你可能需要很多故障保护来使它变得万无一失。例如,您可以在b:col1
或b:col2
中考虑值0(虽然假设您只需要交叉乘法,但您可以执行a:col2
* {{ 1}} / b:col1
除了少了一个例外之外,它对于计算机来说要简单得多(除非是混乱)。缺点是当你开始使用大量数字时,但是我会这样做。我会假设你不会超过1000000 ^ 2这样有点无关紧要。同样,我的代码会假设总有一行b:col2
和a
行。
b
行为如下:如果类型declare @test as table(
staff int,
Type char(1),
col1 decimal(6,2),
col2 decimal(6,2)
)
insert into @test values(1,'a',0,200);
insert into @test values(1,'b',50,2000);
insert into @test values(1,'c',2,200);
insert into @test values(2,'a',0,100);
insert into @test values(2,'b',25,1000);
insert into @test values(2,'c',2,200);
insert into @test values(3,'a',0,150);
insert into @test values(3,'b',35,1500);
insert into @test values(3,'c',2,200);
UPDATE
FirstTable
SET
FirstTable.col1 = CASE FirstTable.[type] WHEN 'a' THEN JoinedTable.col1 * FirstTable.col2 / JoinedTable.col2 ELSE FirstTable.col1 - FirstTable.col1 * JoinedTable.col2 / FirstTable.col2 END,
FirstTable.col2 = CASE FirstTable.[type] WHEN 'a' THEN 0 ELSE FirstTable.col2 - JoinedTable.col2 END
FROM
@test FirstTable
INNER JOIN
@test JoinedTable
ON
FirstTable.staff = JoinedTable.staff AND JoinedTable.[Type] = CASE FirstTable.[Type] WHEN 'a' THEN 'b' ELSE 'a' END
WHERE
FirstTable.[Type] in('a','b')
的col2中有0,则崩溃。如果一个类型为b
或a
的员工有多个行,我相信它会以非确定性的方式采用其中一个,这将导致一些非确定性和潜在错误的结果。如果没有类型b
或a
,则会完全跳过员工。
否则(当它工作时),它只是根据类型更新类型为b
和a
的行。在1个查询中同时更新允许您不使用临时表等,因为新数据不会覆盖旧数据,直到完成整个查询。
另外,尽量不要在列中使用b
之类的关键字,否则最终可能会出现一些错误。