0

所以,假设我有一群捐赠者,他们不定期捐赠。我可以将捐赠者姓名、捐赠金额和捐赠日期放在一个表格中,然后我想做一份报告,显示所有这些信息以及该金额之后所有捐赠的价值。

我知道我可以使用循环解析它,但是有更好的方法吗?

我在这里作弊,不关心将通过的代码并由捐赠者分配交易编号,并确保一切都是正确的顺序。这很容易。

    DECLARE @Donors TABLE (
          ID                INT IDENTITY
        , Name              NVARCHAR(30)
        , NID               INT
        , Amount            DECIMAL(7,2)
        , DonationDate      DATE
        , AmountAfter       DECIMAL(7,2)
        )

    INSERT INTO @Donors VALUES
          ('Adam Zephyr',1,100.00,'2017-01-14',NULL)
        , ('Adam Zephyr',2,200.00,'2017-01-17',NULL)
        , ('Adam Zephyr',3,150.00,'2017-01-20',NULL)
        , ('Braden Yu',1,50.00,'2017-01-11',NULL)
        , ('Braden Yu',2,75.00,'2017-01-19',NULL)

    DECLARE   @Counter1     INT = 0
            , @Name         NVARCHAR(30)

    WHILE @Counter1 < (SELECT MAX(ID) FROM @Donors)
        BEGIN
            SET @Counter1 += 1
            SET @Name = (SELECT Name FROM @Donors WHERE ID = @Counter1)
            UPDATE d1
                SET AmountAfter = (SELECT ISNULL(SUM(Amount),0) FROM @Donors d2 WHERE ID > @Counter1 AND Name = @Name)
                    FROM @Donors d1
                        WHERE d1.ID = @Counter1
        END

    SELECT * FROM @Donors

似乎应该有一种方法可以递归地执行此操作,但我就是无法理解它。

4

1 回答 1

0

这将显示Name我认为是捐赠者的最新捐赠以及该人捐赠的所有金额的总和。也许它更适合NID用于分区。

;with MostRecentDonations as (
    select *,
         row_number() over (partition by Name order by DonationDate desc) as rn,
         sum(Amount) over (partition by Name) as TotalDonations
    from @Donors
)
select * from MostRecentDonations
where rn = 1;

除非您遇到某种性能问题,否则肯定不需要在任何地方存储运行总数。

编辑: 我已经考虑过你的问题,现在我想你只想要一个包含所有交易的运行总计。这也很容易:

select *,
    sum(Amount) over (partition by Name order by DonationDate) as DonationsToDate
from @Donors
order by Name, DonationDate;
于 2017-01-27T23:29:11.603 回答