如何在 SQL Server 中获取一个季度的上个月数据?

Posted

技术标签:

【中文标题】如何在 SQL Server 中获取一个季度的上个月数据?【英文标题】:How to get the last month's data for a quarter in SQL Server? 【发布时间】:2016-12-02 20:47:25 【问题描述】:

我正在尝试创建一个具有数据矩阵的 s-s-rS 报告,该数据矩阵可以按月、按季度或按年分组。我能够每月正确地对我的数据进行分组,但是在尝试按其他任何方式对其进行分组时遇到了问题。

这是一个示例数据集:

Account #     BillingDate     DateActivated      Balance
1             1/1/16          1/1/16             $10,000
1             2/1/16          1/1/16             $9,000
1             3/1/16          1/1/16             $9,500
1             4/1/16          1/1/16             $7,000
1             5/1/16          1/1/16             $4,000
1             6/1/16          1/1/16             $1,000

当我按季度分组时,我只需要该季度最后一个月的数据。例如,对于第一季度,我需要 9,500 美元的余额,而忽略 10,000 美元和 9,000 美元的余额。然而,我的分组是把它们加起来,给我 28,500 美元。


期望的结果

月度报告:

                       DateActivated 1/1/16
BillingDate 1/1/6      $10,000
BillingDate 2/1/6      $9,000
BillingDate 3/1/6      $9,500
BillingDate 4/1/6      $7,000
BillingDate 5/1/6      $4,000
BillingDate 6/1/6      $1,500

季度报告:

                       DateActivated Q1
BillingDate Q1         $9,500
BillingDate Q2         $1,000

我一直在尝试使用子查询,但还没有开始工作。

编辑:我正在使用一个简单的查询来获得上面的结果:

SELECT AccountNumber, BillingDate, DateActivated, Balance
FROM TestTable

【问题讨论】:

你不需要 2 行吗?一个来自 2016 年 3 月 1 日,另一个来自 2016 年 6 月 1 日? 正确,对于季度示例,我省略了 Q2 BillingDate 行。我现在就编辑它。 您能否提供您当前正在使用的 SQL 查询?似乎您只需要按季度分组,其中月份是该组的最大值。 【参考方案1】:

这不是一个简单的公式吗:

=sum(switch(month(Fields!BillingDate.value) = 3 ,Balance ,
 month(Fields!BillingDate.value) = 6 ,Balance ,
month(Fields!BillingDate.value) = 9 ,Balance ,
month(Fields!BillingDate.value) = 12 ,Balance,
 month(Fields!BillingDate.value) =  month(@ParameterThruDate),Balance))

和矩阵组

DatePart(DateInterval.Quarter,Fields.BillingDate.value)

【讨论】:

我遇到了没有完整季度的潜在问题(即最新记录是 11 月,这意味着检查 12 月会给我 null) 第二个虽然我认为这可能有效。数字看起来正确,只需要处理不完整季度的情况。有什么想法吗? 我编辑的公式应该适用于不完整的季度。您可以使用 today() 代替参数。【参考方案2】:

创建两个矩阵,如下所示:

月度报告:

季度报告:

可以使用以下表达式计算 Quarter 行组:

=DatePart(DateInterval.Quarter,Fields!BillingDate.Value)

要获得季度使用:

="BillingDate Q" & DatePart(DateInterval.Quarter,Fields!BillingDate.Value)

要获得最后一个余额值,请使用:

=SUM(
IIF(Fields!BillingDate.Value=MAX(Fields!BillingDate.Value),Fields!Balance.Value,0
))

还可以考虑按帐户创建父行组。

这是结果:

我创建了一个虚拟数据集,其中第四季度的数据不完整(11 月和 12 月没有数据)。如果没有 11 月或 12 月,它会显示 octuber 数据。

如果这有帮助,请告诉我。

【讨论】:

最后一部分出现语法错误。我不认为我有两个等号可以吗?如果我在 IIF 之前删除等号,则会收到 rsAggreateofAggregate 错误。 @ferensilver,是的,我拼错了表达式。 我上个季度没有任何结果。我不需要在帐户上分组。老实说,它也不需要在查询中。我把它放在那里只是为了帮助说明数据。 @ferensilver,您数据中的最后一个季度是什么时候?其余季度的计算是否正确?每个 BillingDate 是否有多个余额值? 第四季度的数据不完整(10 月份已经完成,但 11 月和 12 月的数据不完整)。每个帐单日期每个帐户都有一个余额。我尝试在一个简单的矩阵中重新创建上面的示例以重现错误,但我得到了聚合错误。有任何想法吗? i.imgur.com/ugrY8tj.png【参考方案3】:

在我看来,最好让 sql 完成繁重的工作并保持 s-s-rS RDL 非常简单。我会根据@period_type 参数更新您的查询以仅返回您需要的记录。此示例假设您的数据已按示例数据所示按月分组。如果不是这种情况,请告诉我,我可以更新此示例:

if @period_type = 1 -- monthly
    select
        AccountNumber,
        -- convert BillingDate to text so the data type matches the Quarter strings
        convert(varchar(10),BillingDate,101) as BillingDate
        DateActivated,
        Balance
    from TestTable

if @period_type = 2 -- quarterly
    select
        AccountNumber,
        BillingDate
        DateActivated,
        Balance
    from (
         select
             AccountNumber,
             'Q' + cast(datepart(quarter,BillingDate) as char(1)) as BillingDate
             DateActivated,
             Balance,
             row_number() over(partition by datepart(quarter,BillingDate)
                               order by BillingDate desc) keep_this_1
         from TestTable
         ) tt
    where keep_this_1 = 1

【讨论】:

以上是关于如何在 SQL Server 中获取一个季度的上个月数据?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL日期获取上个季度的第一天和上个季度的最后一天

如何在Java中获取与01/01不同的日期开始的一年的上一个/当前季度和年份的开始和结束日期

如何在 SQL Server 中获取上个月的昨天日期?有人可以帮我解决这个问题吗?

oracle sql 最近5个季度的最后一天

SQL Server如何查找季度、半年和当年的最后一天?

java如何获取当天的上一个月