如何在SQL Server中解决此查询?

时间:2018-10-26 11:09:46

标签: sql sql-server variable-declaration

Sql Fiddle example

我有这个表结构:

    CREATE TABLE IF NOT EXISTS `client` (
  `id` int(6) unsigned NOT NULL,
  `name` varchar(200),
  `balance` decimal NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `client` (`id`, `name`, `balance`) VALUES
  ('1', 'Pepito', '500');


CREATE TABLE IF NOT EXISTS `balance_Movements` (
  `id` int(6) unsigned NOT NULL,
  `clientId` int(6),
  `movementType` varchar(200),
  `import` decimal NOT NULL,
  `dateMovement` datetime,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `balance_Movements` (`id`, `clientid`, `movementType`, `import`, `dateMovement`) VALUES
  ('1', '1', 'payment', '50', '2018/05/11'),
  ('2', '1', 'refund', '25.05', '2018/05/10'),
  ('3', '1', 'refund', '60', '2018/04/06'),
  ('4', '1', 'payment', '100', '2018/04/03');

开始时客户有500欧元->因此,clarify变量将如下所示:

declare @total_balance as decimal;
set @total_balance = (select balance from client where id = 1);

Result
------
500

我需要更改@total_balance的结果后,取最后一行的值:

示例:

Table_balance_Movements
------------------------

    Total
    -----
    450
    475.05
    535.05
    435.05

说明:

450-> 客户从500开始,所以如果移动类型为付款,则需要将客户余额减去导入移动,并将数据保存在@total_balance中以使用以后= 500-50 = 450

475.05-> 我得到@total_balance的值并加25.05,因为在这一行中,移动类型为退款= 450 + 25.05 = 475.05

535.05-> 同样,我从@total_balance变量中获取值,然后查看移动的类型,然后减去或加和import = 475.05 + 60 = 535.05

435.05-> 535.05-100 = 435.05

我想做与此概念类似的事情:

  declare @total_balance as decimal;
set @total_balance = (select balance from client where id = 1);

select (case when movementType = 'payment' then (@total_balance = @total_balance - import) 
             when movementType = 'refund' then (@total_balance = @total_balance + import)  end) as total 
from balance_Movements;

有可能吗?谢谢

4 个答案:

答案 0 :(得分:2)

您可以使用累积和窗口功能来解决此问题。以下内容适用于SQL Server和MySQL 8 +

select c.*,
       (c.balance +
        sum(case when bm.movement_type = 'payment' then - import
                 when bm.movement_type = 'refund' then import
            end) over (partition by c.id order by bm.datemovement)
       ) as net_balance
from client c join
     balance_movements bm
     on bm.clientid = c.id

答案 1 :(得分:1)

您可以只添加退款金额,然后减去付款金额:

SELECT 500 +
(SELECT SUM(import) FROM balance_Movements WHERE movementType = 'refund')
- (SELECT SUM(import) FROM balance_Movements WHERE movementType = 'payment') AS total

结果:435.05

答案 2 :(得分:1)

我认为最简单的方法是将\d+\.\d+\.\d+\.\d+与条件聚合函数窗口函数一起使用,以使用SUM来累加加成

balance

但是,如果您的dbms不支持窗口功能,则可以尝试在SELECT c.balance +SUM(CASE WHEN movementType = 'payment' THEN - import WHEN movementType = 'refund' THEN import ELSE 0 END ) OVER(ORDER BY b.id) Total FROM client c JOIN balance_Movements b on c.id = b.clientid 中正确使用子查询

select

sqlfiddle

答案 3 :(得分:1)

试一下...

IF OBJECT_ID('tempdb..#balance_Movements', 'U') IS NOT NULL 
BEGIN DROP TABLE #balance_Movements; END;

CREATE TABLE #balance_Movements (
    id INT NOT NULL,
    clientId INT,
    movementType VARCHAR (200),
    import DECIMAL (9, 2) NOT NULL,
    dateMovement DATETIME,
    PRIMARY KEY (id)
);
INSERT INTO #balance_Movements (id, clientid, movementType, import, dateMovement) VALUES
  ('1', '1', 'payment', '50', '2018/05/11'),
  ('2', '1', 'refund', '25.05', '2018/05/10'),
  ('3', '1', 'refund', '60', '2018/04/06'),
  ('4', '1', 'payment', '100', '2018/04/03');

--=============================================================

DECLARE @_start DECIMAL(9,2) = 500;

SELECT 
    *,
    running_total = @_start - SUM(CASE WHEN bm.movementType = 'refund' THEN -1 * bm.import ELSE bm.import END) OVER (PARTITION BY bm.clientId ORDER BY bm.dateMovement desc)
FROM
    #balance_Movements bm;

结果...

id          clientId    movementType import     dateMovement            running_total
----------- ----------- ------------ ---------- ----------------------- --------------
1           1           payment      50.00      2018-05-11 00:00:00.000 450.00
2           1           refund       25.05      2018-05-10 00:00:00.000 475.05
3           1           refund       60.00      2018-04-06 00:00:00.000 535.05
4           1           payment      100.00     2018-04-03 00:00:00.000 435.05