以日历季度为列分组

Posted

技术标签:

【中文标题】以日历季度为列分组【英文标题】:Group by with calendar quarter as column 【发布时间】:2015-10-25 17:08:38 【问题描述】:

我想要按日历季度分组的表格一列的总和。更具体地说,我现在拥有的是逐月想要的列的总和:

select month(emitido_date) as mes, year(emitido_date) as ano, ifnull(sum((det.preco * det.quantidade) * (iva.valor/100)),0) as totaliva
from documento as doc
inner join documento_serie as serie on serie.id = doc.documento_serie_id
inner join documento_detail as det on doc.id = det.documento_id
inner join phos_iva as iva on iva.id = det.iva_id
where serie.documento_categoria_id = 2 or  serie.documento_categoria_id = 3
group by mes, ano 
order by mes, ano desc

上面的代码很好,对我有用。它返回我想要按月分组的列的总和。例如:1 月: 100,2 月: 200,3 月: 300。直到 12 月为止。

我的问题是如何按日历季度分组。具体来说,寻找上面的例子,现在我想创建一个查询,它给我 [January, February, March]=600, [April, May, June], [July, August, September] 的值的总和]、[10 月、11 月、12 月]。我尝试使用下面的代码,但出现错误:

1111 - 组函数的使用无效。

select 
sum(case when month(emitido_date) in (1,2,3) then ifnull(sum(det.quantidade),0) else 0 end) as Tri1,
sum(case when month(emitido_date) in (4,5,6) then ifnull(sum(det.quantidade),0) else 0 end) as Tri2,
    select 
    sum(case when month(emitido_date) in (1,2,3) then ifnull(sum((det.preco * det.quantidade) * (iva.valor/100)),0) else 0 end) as Tri1,
    sum(case when month(emitido_date) in (4,5,6) then ifnull(sum((det.preco * det.quantidade) * (iva.valor/100)),0) else 0 end) as Tri2,
    sum(case when month(emitido_date) in (7,8,9) then ifnull(sum((det.preco * det.quantidade) * (iva.valor/100)),0) else 0 end) as Tri3,
    sum(case when month(emitido_date) in (10,11,12) then ifnull(sum((det.preco * det.quantidade) * (iva.valor/100)),0) else 0 end) as Tri4,
    year(emitido_date) as ano
    from documento as doc
    inner join documento_serie as serie on serie.id = doc.documento_serie_id
    inner join documento_detail as det on doc.id = det.documento_id
    inner join phos_iva as iva on iva.id = det.iva_id
    where serie.documento_categoria_id = 3 
    group by year(emitido_date)

怎么了?

【问题讨论】:

我不知道 3 in 3 months 是什么意思。如果您愿意,请考虑遵循这个简单的两步操作: 1. 如果您还没有这样做,请提供适当的 DDL(和/或 sqlfiddle),以便我们可以更轻松地复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。 “3个月内3个”是指以下期间一列的总和:[Jan,mar],[apr,jun],[jul,sept],[oct,dec] "3 in 3" 不是你用英语怎么说的。在这种情况下,它翻译为“3 by 3 个月”,很难在句子中与“group by”结合使用。更好的说法可能是“按季度分组”。 对不起我的英语。我已经编辑了问题。 【参考方案1】:

您不能嵌套聚合函数。但你不需要。我想你想要:

select sum(case when month(emitido_date) in (1, 2,3 )
                then det.quantidade else 0 end) as Tri1,
       sum(case when month(emitido_date) in (4, 5, 6)
                then det.quantidade else 0 end) as Tri2,
       sum(case when month(emitido_date) in (7, 8, 9)
                then det.quantidade else 0 end) as Tri3,
       sum(case when month(emitido_date) in (10, 11, 12)
                then det.quantidade else 0 end) as Tri4,
       year(emitido_date) as ano

【讨论】:

我只是把 de sum(det.quantidade) 让问题更清晰。我想要的总和是:'ifnull(sum((det.preco * det.quantidade) * (iva.valor/100)),0) as totaliva' @HugoMachado 。 . .我们只能回答被问到的问题。如果您还有其他问题,那么您应该再问一个问题。确保它是您想要回答的问题,样本数据和所需结果有助于传达您想要的结果。【参考方案2】:

尝试GROUP BY year(emitido_date) 而不是group by ano

还将ifnull(sum(det.quantidade),0) 替换为ifnull(det.quantidade,0),因为您已经在CASE 子句之外拥有SUM

【讨论】:

如果我的总和是 'ifnull(sum((det.preco * det.quantidade) * (iva.valor/100)),0) as totaliva'? 如果这对您有用并且您不再收到错误,我建议您提出一个关于如何将查询转换为使用新公式的新问题。

以上是关于以日历季度为列分组的主要内容,如果未能解决你的问题,请参考以下文章

Hive 中的联合分组结果集

将按月分组的行计数为列

按日期分组时将整数行转换为列

Tsql 将行转置为列,按列分组

分组后将行值显示为列-Oracle

按 Id 分组行并将月份和 order_count 连接为列?