计算sql server 2008的累计和

时间:2017-07-14 07:19:52

标签: sql-server sql-server-2008

我在SQL Server 2008中有一个表,如:

tblCustomer

现在我想要像

这样的表格
Date        Description     Debit      Credit     Balance
-----------------------------------------------------------
2017-05-11  xxx             25000.00              -25000.00
2017-05-11  aaa                        20000.00    -5000.00
2017-05-12  xyz             5000.00               -10000.00
2017-06-01  abc                        10000.00        0.00

<table border=1>
  <tr>
    <th> Date</th>
    <th>Description</th>
    <th>Debit</th>
    <th>Credit</th>
    <th>Balance</th>
  </tr>
  <tr>
    <td> 2017-05-11</td>
    <td>xxx</td>
    <td>25000.00</td>
    <td></td>
    <td>-25000.00</td>
  </tr>
  <tr>
    <td> 2017-05-11</td>
    <td>aaa</td>
    <td></td>
    <td>20000.00</td>
    <td>-5000.00</td>
  </tr>
  <tr>
    <td> 2017-05-12</td>
    <td>xyz</td>
    <td>5000.00</td>
    <td></td>
    <td>-10000.00</td>
  </tr>
  <tr>
    <td> 2017-06-01</td>
    <td>abc</td>
    <td></td>
    <td>10000.00</td>
    <td>0.00</td>
  </tr>
</table>

请不要使用SQL 2012关键字,如分区依据,未绑定的行等。因为我想在SQL Server 2008中使用它。

我在2012年完成了它,看起来像:

SELECT  [Date], 
        [Description], 
        ( CASE WHEN DrCr = 'Dr' THEN Amount END ) AS Debit, 
        ( CASE WHEN DrCr = 'Cr' THEN Amount END ) AS Credit, 
        SUM( CASE WHEN DrCr = 'Dr' THEN - Amount ELSE Amount END ) OVER ( PARTITION BY CustomerID ORDER BY DATE ) AS Balance
FROM tblCustomer
WHERE CustomerID = '1'

3 个答案:

答案 0 :(得分:0)

这是一个基于集合的解决方案,用于获取您想要的结果,如果您还想按CustomerId分组,则没有回答,所以我没有包含它,因为您的结果集不包含它:

    declare @t table (dt date, descr varchar(100), drcr char(2), am decimal(10,2));
    insert into @t values
    ('20170511', 'xxx', 'Dr', 25000), 
    ('20170511', 'aaa', 'Cr', 20000), 
    ('20170512', 'xyz', 'Dr', 5000), 
    ('20170601', 'abc', 'Cr', 10000), 
    ('20170601', 'abc', 'Cr', 10000);


    with cte as
    (
    select dt, descr, 
           Debit, Credit,
           am_signed,
           row_number() over(order by dt, Credit) as rn
    from @t cross apply
         (
           select
           case drcr 
                when 'Dr' then am
           end as Debit,

           case drcr 
                when 'Cr' then am
           end as Credit,

           case drcr 
                when 'Dr' then -am
                when 'Cr' then am
           end as am_signed

         )a
    )       

    ,cte1 as
    (
    select t1.dt, t1.descr, t1.Debit, t1.Credit, t1.am_signed,
           sum(t2.am_signed) as balance, t1.rn
    from cte as t1 
         join cte as t2 
             on t2.rn <= t1.rn
    group by t1.dt, t1.descr, t1.Debit, t1.Credit, t1.am_signed, t1.rn
    )

    select dt, descr, Debit, Credit, balance
    from cte1
    order by rn;

............................................... ...................

致@Jayvee:检查How to Use Microsoft SQL Server 2012's Window Functions

  

SQL Server 2012(以前代号为SQL Server Denali)介绍   几个重要的T-SQL可编程功能;本文重点介绍   在其中一个功能 - 窗口功能。 SQL Server 2005 是   支持窗口功能的第一个里程碑;它介绍了窗口   排名函数(ROW_NUMBER,RANK,DENSE_RANK和NTILE)以及   作为仅对窗口聚合函数 - 的有限支持   分区条款 SQL Server 2012增强了对窗口的支持   聚合函数通过引入窗口订单 和框架***子句*** s,   支持偏移函数(LAG,LEAD,FIRST_VALUE和LAST_VALUE),   并支持窗口分配功能(PERCENT_RANK,   CUME_DIST,PERCENTILE_DISC和PERCENTILE_CONT)。

答案 1 :(得分:0)

 with tc as
    (salect *, row_number() over(order by date, CrDR) as rownum)


    SELECT  [Date], 
            [Description], 
            ( CASE WHEN DrCr = 'Dr' THEN Amount END ) AS Debit, 
            ( CASE WHEN DrCr = 'Cr' THEN Amount END ) AS Credit, 
            select (SUM( CASE WHEN DrCr = 'Dr' THEN - Amount ELSE Amount END ) from tc tc1 where tc1.rownum<=tc.rownum) AS Balance
    FROM tblCustomer tc
    WHERE CustomerID = '1'

如果您想要多个客户,可以在子查询中添加tc1.customerid = tc.customerid

答案 2 :(得分:0)

我在你的帮助下解决了这个问题。我的代码是这样的:

declare @t table (dt date, descr varchar(100), drcr char(2), am decimal(10,2));
    insert into @t values
    ('20170511', 'xxx', 'Dr', 25000), 
    ('20170511', 'aaa', 'Cr', 20000), 
    ('20170512', 'xyz', 'Dr', 5000), 
    ('20170601', 'abc', 'Cr', 10000), 
    ('20170601', 'abc', 'Cr', 10000);

val rdd = sc.newAPIHadoopFile("<filepath>", classOf[ParagraphInputFormat], classOf[LongWritable], classOf[Text], sc.hadoopConfiguration)

,最终输出为:enter image description here