如何在sql server中解决此查询?

如何在sql server中解决此查询?,sql,sql-server,variable-declaration,Sql,Sql Server,Variable Declaration,我有以下表格结构: 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', 'Pepi

我有以下表格结构:

    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€->所以declare变量如下:

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

Result
------
500
SELECT 500 +
(SELECT SUM(import) FROM balance_Movements WHERE movementType = 'refund')
- (SELECT SUM(import) FROM balance_Movements WHERE movementType = 'payment') AS total
我需要在@total_balance的结果之后进行更改,取最后一行的值:

例如:

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

    Total
    -----
    450
    475.05
    535.05
    435.05
说明:

450->客户端以500开头,因此如果移动类型是付款,我需要将客户端余额减去导入移动,并将数据保存在@total_balance中,以便稍后使用它=500-50=450

475.05->我得到@total_balance和sum 25.05的值,因为在这一行中,移动的类型是return=450+25.05=475.05

535.05->同样,我从@total_balance变量中获取值,然后查看移动的类型,并减去或求和导入=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;

有可能吗?谢谢

您可以使用累积和窗口函数解决此问题。以下内容将在SQLServer和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

可以使用累积和窗口函数解决此问题。以下内容将在SQLServer和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

您可以将退款总额相加,再减去付款总额,如下所示:

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

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

结果:435.05

您可以将退款总额相加,然后减去付款总额,如下所示:

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

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

结果:435.05

我认为最简单的方法是使用带条件的求和聚合函数窗口函数来获得带余额的累加

但如果您的dbms不支持窗口功能,您可以尝试在select中正确使用子查询


我认为最简单的方法是使用SUM with condition aggregate函数window函数来获得累加with balance

但如果您的dbms不支持窗口功能,您可以尝试在select中正确使用子查询

试一试

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
试一试

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

您使用的是SQL Server还是MySQL?如果您使用的是SQL Server,为什么示例代码和SQL Fiddle使用的是MySQL?@GordonLinoff我想他想要一个SQL Server解决方案,因为他在MySQL上有它。@Sami he或she:?@BarbarosÖzhan OP,所以他:-他不是她:-您使用的是SQL Server还是MySQL?如果您使用的是SQL Server,为什么示例代码和SQL Fiddle使用的是MySQL?@GordonLinoff我想他想要一个SQL Server解决方案,因为他在MySQL上有它。@Sami he或she:?@BarbarosÖzhan OP,所以他:-他不是吗-