【问题标题】:SQL Server aggregate over range of datesSQL Server 在日期范围内聚合
【发布时间】:2016-07-29 11:43:29
【问题描述】:

我使用的是 SQL Server 2014。我需要汇总按客户和位置划分或分组的日期范围内的总计(总和)。关键是获取所有调整金额并在它们适用于开票交易日期时对其进行汇总。

因此,在最后一个账单日期之后但小于下一个账单日期的所有调整都需要汇总并与账单金额一起很好地呈现。

查看示例:

+------------------+------------+------------+------------------+--------------------+
| TRANSACTION_TYPE | CUSTOMERID | LOCATIONID | TRANSACTION DATE | TRANSACTION AMOUNT |
+------------------+------------+------------+------------------+--------------------+
| bill             | 215        | 102        | 7/7/2016         | $100.00            |
| bill             | 215        | 102        | 6/6/2016         | $121.00            |
| adj              | 215        | 102        | 6/1/2016         | $22.00             |
| adj              | 215        | 102        | 5/8/2016         | $0.35              |
| adj              | 215        | 102        | 5/7/2016         | $5.00              |
| bill             | 215        | 102        | 5/6/2016         | $115.00            |
| bill             | 215        | 102        | 4/7/2016         | $200.00            |
| adj              | 215        | 102        | 4/2/2016         | $4.35              |
| adj              | 215        | 102        | 4/1/2016         | $(0.50)            |
| adj              | 215        | 102        | 3/28/2016        | $33.00             |
| bill             | 215        | 102        | 3/28/2016        | $75.00             |
| adj              | 215        | 102        | 3/5/2016         | $0.33              |
| bill             | 215        | 102        | 3/3/2016         | $99.00             |
+------------------+------------+------------+------------------+--------------------+

我想看到的是以下内容:

    +------------------+------------+------------+------------------+-------------+-------------------+
| TRANSACTION_TYPE | CUSTOMERID | LOCATIONID | TRANSACTION DATE | BILL AMOUNT | ADJUSTMENT AMOUNT |
+------------------+------------+------------+------------------+-------------+-------------------+
| bill             | 215        | 102        | 7/7/2016         | $100.00     | $-                |
| bill             | 215        | 102        | 6/6/2016         | $121.00     | $27.35            |
| bill             | 215        | 102        | 5/6/2016         | $115.00     | $-                |
| bill             | 215        | 102        | 4/7/2016         | $200.00     | $36.85            |
| bill             | 215        | 102        | 3/28/2016        | $75.00      | $0.33             |
| bill             | 215        | 102        | 3/3/2016         | $99.00      | $-                |
+------------------+------------+------------+------------------+-------------+-------------------+

【问题讨论】:

    标签: sql sql-server-2014 aggregates


    【解决方案1】:

    你需要:

    • 首先将表设想为 TransactionType 上的两个(虚拟)子表;
    • 然后使用 LEAD 函数获取要应用的调整的日期范围;和
    • 最终执行 eft 连接。

    以下未经测试的 SQL:

    with
    BillData as (
        select
            TransactionType,
            CustomerID,
            LocationID,
            TransactionDate,
            TransactionAmount,
            lead(TransactionDate, 1) over (partition by CustomerID 
                                           order by TransactionDate) as NextDate
        from @data bill
        where TransactionType = 'bill'
    ),
    AdjData as (
        select
            CustomerID,
            TransactionDate,
            sum(TransactionAmount) as AdjAmount
        from @data adj
        where TransactionType = 'adj'
    )
    select
        bill.TransactionType,
        bill.CustomerID,
        bill.LocationID,
        bill.TransactionDate,
        sum(TransactionAmount)  as BillAmount,
        sum(AdjAmount)          as AdjAmount
    from BillData bill
    left join AdjData adj
        on adj.CustomerID = bill.CustomerID
       and bill.TransactionDate <= adj.TransactionDate
       and adj.TransactionDate < bill.NextDate
    group by
        bill.TransactionType,
        bill.CustomerID,
        bill.LocationID,
        bill.TransactionDate
    ;
    

    【讨论】:

    • 感谢您的帮助。该查询并不完全有效,但它确实为我指明了正确的方向,所以我会接受这个作为正确答案。再次感谢!
    【解决方案2】:

    这就是我最终做的:

            select
            bill.TransactionType,
            bill.CustomerID,
            bill.LocationID,
            bill.TransactionDate,
            TransactionAmount  as BillAmount,
            sum(AdjAmount)          as AdjAmount
        from 
        (
            select
                TransactionType,
                CustomerID,
                LocationID,
                TransactionDate,
                TransactionAmount,
                lag(TransactionDate, 1) over (partition by CustomerID, LocationID
                                               order by TransactionDate) as PreviousDate --NextDate
            from test1
            where TransactionType = 'bill'
        ) as bill
        left join
        (
            select
                CustomerID,
                LocationID,
                TransactionDate,
                TransactionAmount as AdjAmount
            from test1
            where TransactionType = 'adj'
        ) as adj
        ON 
            adj.CustomerID = bill.CustomerID
            and adj.LocationID = bill.LocationID
        and adj.TransactionDate >= bill.PreviousDate
        and adj.TransactionDate < bill.TransactionDate
        group by
            bill.TransactionType,
            bill.CustomerID,
            bill.LocationID,
            bill.TransactionDate,
            bill.TransactionAmount
        order by 4 desc
    

    【讨论】:

      猜你喜欢
      • 2018-09-02
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      相关资源
      最近更新 更多