如何减少一行中的列的值?
How to reduce the value of a column in a row with?
我有一个包含两列的 table:
No Value
1 20
2 10
3 50
4 35
5 17
我还有一个变量或参数,其中变量会减少一行中某列的值。
所以,如果我的变量 V = 5
那么我的专栏将更新:
No Value
1 15
2 10
3 50
4 35
5 17
或者如果 V = 50
那么:
No Value
1 0
2 0
3 30
4 35
5 17
我该怎么做?
首先准备结构和数据:
CREATE TABLE TAB
(
[No] int identity(1,1) primary key,
[Value] int
);
INSERT INTO TAB VALUES (20);
INSERT INTO TAB VALUES (10);
INSERT INTO TAB VALUES (50);
INSERT INTO TAB VALUES (35);
INSERT INTO TAB VALUES (17);
所以现在我们定义您的变量以减少 [Value]:
DECLARE @var int
SET @var = 5
现在您可以查询您的 table:
SELECT [No], CASE WHEN [Value] - @var < 0 THEN 0 ELSE [Value] - @var END AS [Value]
FROM TAB
很简单。您可以将变量设置为 50 再试一次。
这是此示例的 fiddle。
使用 CTE 可以是选项之一
declare @Values table
(
[No] int identity(1,1) not null,
Value int not null
)
declare @DeductAmount int = 50
INSERT @Values VALUES (20), (10), (50), (35), (17)
;WITH cte AS
(
SELECT *,
@DeductAmount - CASE WHEN Value >= @DeductAmount THEN @DeductAmount ELSE Value END AS RemainDeductAmount,
Value - CASE WHEN Value >= @DeductAmount THEN @DeductAmount ELSE Value END DeductedValue
FROM @Values WHERE [No] = 1
UNION ALL
SELECT
v.*,
cte.RemainDeductAmount - CASE WHEN v.Value >= cte.RemainDeductAmount THEN cte.RemainDeductAmount ELSE v.Value END,
v.Value - CASE WHEN v.Value >= cte.RemainDeductAmount THEN cte.RemainDeductAmount ELSE v.Value END DeductedValue
FROM @Values v INNER JOIN cte ON v.[No] = cte.[No] + 1
)
UPDATE target SET Value = DeductedValue
FROM @Values target INNER JOIN cte ON target.[No] = cte.[No]
SELECT * FROM @Values
cte中的秘密
No Value RemainDeductAmount DeductedValue
----------- ----------- ------------------ -------------
1 20 30 0
2 10 20 0
3 50 0 30
4 35 0 35
5 17 0 17
用你的变量改变 50
查询:
SELECT t.No,
CASE WHEN SUM(t.Value)over(ORDER BY t.No) - 50 <0 THEN 0
WHEN SUM(t2.Value)over(ORDER BY t2.No) > 50
AND SUM(t.Value)over(ORDER BY t.No) >50 THEN t.Value
ELSE SUM(t.Value)over(ORDER BY t.No) - 50
END AS Value
FROM Table1 t
LEFT JOIN Table1 t2 ON t.No - 1 = t2.No
这是另一个版本:
DECLARE @t TABLE(ID INT IDENTITY(1, 1) , v INT )
DECLARE @x INT = 5
INSERT INTO @t VALUES ( 20 ), ( 10 ), ( 50 ), ( 35 ), ( 17 );
WITH cte
AS ( SELECT * ,
@x - ( SELECT ISNULL(SUM(v), 0) AS v
FROM @t t2
WHERE t2.ID <= t1.ID) s
FROM @t t1
)
SELECT ID ,
CASE WHEN s >= 0 THEN 0
WHEN s < 0 AND v + s > 0 THEN -s
ELSE v END
FROM cte
DECLARE @qty int
SET @qty= 50
WHILE @qty> 0
BEGIN
SELECT @qty= @qty- value
FROM table
WHERE no = (SELECT MIN(no) FROM table WHERE value > 0)
IF @qty< 0
BEGIN
UPDATE table
SET value = ABS(@qty)
WHERE (SELECT MIN(no) FROM table WHERE value > 0)
END
ELSE
BEGIN
UPDATE table
SET value = 0
WHERE (SELECT MIN(no) FROM table WHERE value > 0)
END
END
我有一个包含两列的 table:
No Value
1 20
2 10
3 50
4 35
5 17
我还有一个变量或参数,其中变量会减少一行中某列的值。
所以,如果我的变量 V = 5
那么我的专栏将更新:
No Value
1 15
2 10
3 50
4 35
5 17
或者如果 V = 50
那么:
No Value
1 0
2 0
3 30
4 35
5 17
我该怎么做?
首先准备结构和数据:
CREATE TABLE TAB
(
[No] int identity(1,1) primary key,
[Value] int
);
INSERT INTO TAB VALUES (20);
INSERT INTO TAB VALUES (10);
INSERT INTO TAB VALUES (50);
INSERT INTO TAB VALUES (35);
INSERT INTO TAB VALUES (17);
所以现在我们定义您的变量以减少 [Value]:
DECLARE @var int
SET @var = 5
现在您可以查询您的 table:
SELECT [No], CASE WHEN [Value] - @var < 0 THEN 0 ELSE [Value] - @var END AS [Value]
FROM TAB
很简单。您可以将变量设置为 50 再试一次。 这是此示例的 fiddle。
使用 CTE 可以是选项之一
declare @Values table
(
[No] int identity(1,1) not null,
Value int not null
)
declare @DeductAmount int = 50
INSERT @Values VALUES (20), (10), (50), (35), (17)
;WITH cte AS
(
SELECT *,
@DeductAmount - CASE WHEN Value >= @DeductAmount THEN @DeductAmount ELSE Value END AS RemainDeductAmount,
Value - CASE WHEN Value >= @DeductAmount THEN @DeductAmount ELSE Value END DeductedValue
FROM @Values WHERE [No] = 1
UNION ALL
SELECT
v.*,
cte.RemainDeductAmount - CASE WHEN v.Value >= cte.RemainDeductAmount THEN cte.RemainDeductAmount ELSE v.Value END,
v.Value - CASE WHEN v.Value >= cte.RemainDeductAmount THEN cte.RemainDeductAmount ELSE v.Value END DeductedValue
FROM @Values v INNER JOIN cte ON v.[No] = cte.[No] + 1
)
UPDATE target SET Value = DeductedValue
FROM @Values target INNER JOIN cte ON target.[No] = cte.[No]
SELECT * FROM @Values
cte中的秘密
No Value RemainDeductAmount DeductedValue
----------- ----------- ------------------ -------------
1 20 30 0
2 10 20 0
3 50 0 30
4 35 0 35
5 17 0 17
用你的变量改变 50
查询:
SELECT t.No,
CASE WHEN SUM(t.Value)over(ORDER BY t.No) - 50 <0 THEN 0
WHEN SUM(t2.Value)over(ORDER BY t2.No) > 50
AND SUM(t.Value)over(ORDER BY t.No) >50 THEN t.Value
ELSE SUM(t.Value)over(ORDER BY t.No) - 50
END AS Value
FROM Table1 t
LEFT JOIN Table1 t2 ON t.No - 1 = t2.No
这是另一个版本:
DECLARE @t TABLE(ID INT IDENTITY(1, 1) , v INT )
DECLARE @x INT = 5
INSERT INTO @t VALUES ( 20 ), ( 10 ), ( 50 ), ( 35 ), ( 17 );
WITH cte
AS ( SELECT * ,
@x - ( SELECT ISNULL(SUM(v), 0) AS v
FROM @t t2
WHERE t2.ID <= t1.ID) s
FROM @t t1
)
SELECT ID ,
CASE WHEN s >= 0 THEN 0
WHEN s < 0 AND v + s > 0 THEN -s
ELSE v END
FROM cte
DECLARE @qty int
SET @qty= 50
WHILE @qty> 0
BEGIN
SELECT @qty= @qty- value
FROM table
WHERE no = (SELECT MIN(no) FROM table WHERE value > 0)
IF @qty< 0
BEGIN
UPDATE table
SET value = ABS(@qty)
WHERE (SELECT MIN(no) FROM table WHERE value > 0)
END
ELSE
BEGIN
UPDATE table
SET value = 0
WHERE (SELECT MIN(no) FROM table WHERE value > 0)
END
END