使用SQL Select语句进行空计算

时间:2011-01-22 12:51:03

标签: sql sql-server tsql

我有以下表

Input           Output
---------------------------------
12.22           
                2.22

如果我通过以下Sql语句:

按库存组输入,输出,平衡=总和(输入 - 输出)

所以输出是:

Input            Output       Balance
--------------------------------------
12.22            NULL         NULL
NULL             2.22         NULL

如果我想要输出如下:

Input            Output       Balance
--------------------------------------
12.22                         12.22
                 2.22         10.00

什么是SQL Transact语句?

我的表格结构如下:

companyID   int
transID     int    -- Primary Key (Auto Increment)
Date        datetime
particulars varchar
input       decimal
output      decimal

注意: - 我已经在输入和输出列中应用了分组依据功能,因为transID列是自动增量所以它不会产生差异因此它应该是显示表的所有行。

5 个答案:

答案 0 :(得分:3)

Select Input,
       Output,
       @runbal:=@runbal+SUM(COALESCE(Input, 0) - COALESCE(Output, 0)) AS Balance
from (select @runbal:=0) rt,Stock 
group by Input,Output

答案 1 :(得分:3)

我认为这可能对你有用。首先,这是我如何定义我的测试表和测试数据:

declare @stock table (
  transId int not null identity(1,1), 
  [date] date not null, -- use datetime if not using SQL Server 2008
  input decimal(7,2) null, 
  [output] decimal(7,2) null
);

insert into @stock values
('1/23/2011', 12.22, null),
('1/23/2011', null, 2.22),
('1/24/2011', 16, null),
('1/24/2011', 3.76, null),
('1/24/2011', null, 5.50);

以下是我用于生成您在问题中指定的结果的选择。该查询为给定日期的事务ID顺序生成所有事务的总计。如果您想计算多天的总数,请注释掉AND b.[date] = a.[date]行。

select 
  [date],
  input = isnull(input,0), 
  [output] = isnull([output],0),
  balance = (isnull(input,0)-isnull([output],0)) +
        isnull((
          select 
            sum((isnull(input,0)-isnull([output],0)))
          from @stock b
          where b.transId < a.transId
          and b.[date] = a.[date] -- comment this for totals over multiple dates
        ),0)
from @stock a
order by transId;

此查询提供:

date        input   output  balance
2011-01-23  12.22   0.00    12.22
2011-01-23   0.00   2.22    10.00
2011-01-24  16.00   0.00    16.00
2011-01-24   3.76   0.00    19.76
2011-01-24   0.00   5.50    14.26

作为脚注,由于每个事务的运行总值始终相同,我建议在表中添加一个余额列,并在插入事务行时计算余额列的值。这样,您只需查看最后一笔交易的余额即可确定所插入交易的余额应该是什么。

答案 2 :(得分:2)

涉及null的任何“正常”操作都会产生null。

了解COALESCE;如果COALESCE(foo, 0)不为空,则使用foo返回foo的事实,如果{{1}}为空则返回0。

答案 3 :(得分:0)

这是Sql-2000服务器解决方案我想与 arcain的解决方案附近的社区分享

我在这里使用合并功能代替 ISNULL

select
transID,
input,
output,
runningtotal =  coalesce(input,0)- coalesce(output,0) +
coalesce(
(select
sum(coalesce(input,0)-coalesce(output,0))
from stock b
where b.transID < a.transID
),0)
from stock a
order by transID

感谢.......

答案 4 :(得分:0)

使用 arcain 样本表,您可以使用以下查询,这些查询利用了窗口功能来完成工作。

--arcain sample table 

declare @stock table (
      transId int not null identity(1,1), 
      [date] date not null, -- use datetime if not using SQL Server 2008
      input decimal(7,2) null, 
      [output] decimal(7,2) null
    );

insert into @stock values
('1/23/2011', 12.22, null),
('1/23/2011', null, 2.22),
('1/24/2011', 16, null),
('1/24/2011', 3.76, null),
('1/24/2011', null, 5.50);

查询

SELECT *,
        SUM( COALESCE(input,0) - COALESCE(output,0) ) 
            OVER (PARTITION BY date ORDER BY date,transId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM @stock