Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使用减少行中列的值?_Sql_Sql Server_Row - Fatal编程技术网

Sql 如何使用减少行中列的值?

Sql 如何使用减少行中列的值?,sql,sql-server,row,Sql,Sql Server,Row,我有一个包含两列的表: 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,则: 我该怎么做?首先准备结构和数据: CREATE TABLE TAB ( [No] int identity(1,1) primary key

我有一个包含两列的表:

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,则:


我该怎么做?

首先准备结构和数据:

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
现在您可以查询您的表:

SELECT [No], CASE WHEN [Value] - @var < 0 THEN 0 ELSE [Value] - @var END AS [Value] 
FROM TAB 
很简单。您可以将变量设置为50,然后重试。
下面是本例的示例。

使用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

如果V变量为5或50,则根据什么逻辑过滤数据?如果V是50,为什么要将0表示为15和10?在CASE语句中实现的逻辑不正确。例如,从前两个数字中减去5将返回15和10,而基于输入数据的逻辑将返回15和5。因此,不是确切的答案,而是最可能的假设。
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