You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL按年分组统计各季度太阳能发电量的SQL写法

问题场景

现有存储10年太阳能面板发电数据的MySQL表DTP,数据采集粒度为每10分钟1条,仅保存发电量大于0的记录,表结构如下:

#,  Field,      Type,           Null,   Key,    Default,    Extra
1,  'PWR',      'decimal(5,3)', 'NO',   '',     NULL,       ''
2,  'idDTP',    'int(11)',      'NO',   'PRI',  NULL,       'auto_increment'
3,  'DT',       'datetime',     'NO',   '',     NULL,       ''

需求为构造SQL查询,实现结果按年份分行,每行返回4个统计值,分别对应该年度Q1-Q4四个季度的发电功率PWR总和。


此前尝试的问题

之前参考其他业务场景的SQL示例改造的代码无法正常运行,不确定实现思路是否正确,改造后的错误代码如下:

SELECT Year,SUM(Quarter1) AS Quarter1,SUM(Quarter2) AS Quarter2,SUM(Quarter3) AS Quarter3,SUM(Quarter4) AS Quarter4
FROM
(
    SELECT YEAR(DT) AS 'Year' ,
    Quarter1 = CASE(DATEPART(q, DTP.DT))
    WHEN 1 THEN SUM(DTP.DT)
    ELSE 0
    END,
    Quarter2 = CASE(DATEPART(q, DTP.DT))
    WHEN 2 THEN SUM(DTP.DT)
    ELSE 0
    END,
    Quarter3 = CASE(DATEPART(q, DTP.DT))
    WHEN 3 THEN SUM(DTP.DT)
    ELSE 0
    END,
    Quarter4 = CASE(DATEPART(q, DTP.DT))
    WHEN 4 THEN SUM(DTP.DT)
    ELSE 0
    END
 FROM DTP LEFT JOIN PWR ON DTP.DT = Customers.CustomerID
 LEFT JOIN [Order Details] ON [Order Details].OrderID = Orders.OrderID
 GROUP BY CompanyName, YEAR(OrderDate), DATEPART(q, OrderDate)
 )C
 GROUP BY CompanyName,Year

以下为2012年2-3月的部分源数据样例,全量数据格式与样例一致:

'160851', '2012-02-29 08:00:00', '0.030'
'160852', '2012-02-29 08:10:00', '0.066'
'160853', '2012-02-29 08:20:00', '0.072'
'160854', '2012-02-29 08:30:00', '0.060'
'160855', '2012-02-29 08:40:00', '0.090'
'160856', '2012-02-29 08:50:00', '0.102'
'160857', '2012-02-29 09:00:00', '0.084'
'160858', '2012-02-29 09:10:00', '0.132'
'160859', '2012-02-29 09:20:00', '0.144'
'160860', '2012-02-29 09:30:00', '0.138'
'160861', '2012-02-29 09:40:00', '0.150'
'160862', '2012-02-29 09:50:00', '0.174'
'160863', '2012-02-29 10:00:00', '0.174'
'160864', '2012-02-29 10:10:00', '0.162'

实现思路
  • 采用条件聚合的方式完成行转列统计,不需要冗余的多表关联、嵌套子查询
  • MySQL中使用内置QUARTER(日期字段)函数获取日期所属季度,返回值为1-4,分别对应Q1到Q4
  • 直接按年份分组,分组内通过CASE WHEN判断每条记录所属季度,匹配对应季度时返回功率值PWR,否则返回0,再对返回值求和即可得到对应季度的功率总和

可直接运行的正确SQL
SELECT
  YEAR(DT) AS `Year`,
  SUM(CASE WHEN QUARTER(DT) = 1 THEN PWR ELSE 0 END) AS Quarter1,
  SUM(CASE WHEN QUARTER(DT) = 2 THEN PWR ELSE 0 END) AS Quarter2,
  SUM(CASE WHEN QUARTER(DT) = 3 THEN PWR ELSE 0 END) AS Quarter3,
  SUM(CASE WHEN QUARTER(DT) = 4 THEN PWR ELSE 0 END) AS Quarter4
FROM DTP
GROUP BY YEAR(DT)
ORDER BY `Year`;

原有代码错误点说明
  • 残留参考示例的无关逻辑:关联了当前场景不存在的PWR、Customers、Orders、Order Details业务表,关联条件也完全不匹配
  • 数据库函数不兼容:DATEPART是SQL Server的日期函数,MySQL无该语法
  • 聚合逻辑错误:CASE语句内错误嵌套聚合函数,且求和字段误写为时间字段DT,而非需要统计的功率字段PWR
  • 分组字段错误:分组用的CompanyName、OrderDate等字段在DTP表中不存在,属于示例代码残留

内容的提问来源于stack exchange,提问作者Greg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:09:26