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

如何修改SUM CASE查询实现多日期score求和及同名字段累加?

问题描述

现有代码:

$scoreboard->selectRaw("SUM(CASE WHEN tgl IN ($dateFormat) THEN score ELSE 0 END) AS '$day'");

这段代码中,tgl字段会匹配$dateFormat(格式如'2022-12-01', '2023-01-01', '2023-02-01')中的值,匹配成功则累加score字段。但当前逻辑仅做OR判断,无法实现指定多个日期的score总和统计。

需解决两个问题:

  1. 如何改写该查询,实现对指定多个日期的score求和?
  2. 若两个查询使用相同的AS $day(例如AS Day1),第二个查询的数据是否会累加到第一个中?

示例数据

Nametglscore
A2022-12-01100
A2022-12-01200
A2022-12-01300
A2022-12-02400
A2022-01-01100
A2022-01-01100
A2022-01-03200
A2022-02-01100
A2022-02-01200
A2022-02-02300

期望输出

NameDay 1Day 2Day 3
A600 (sum of 2022-12-01)400 (sum of 2022-12-02)0 (无对应日期数据)
A100 (sum of 2022-01-01)0 (无对应日期数据)200 (sum of 2022-01-03)
A300 (sum of 2022-02-01)300 (sum of 2022-02-02)0 (无对应日期数据)

解答

1. 改写查询实现多日期score求和

核心是要明确分组维度,并为每个目标日期单独编写统计逻辑,同时补充GROUP BY子句来得到分组后的结果:

场景1:按单个日期分别统计(对应期望输出的Day1/Day2/Day3)

如果需要对每个指定日期单独求和,要为每个日期写独立的SUM(CASE...),再按Name和日期所属的月份分组:

// 构建每个日期的统计字段
$selectFields = [
    "SUM(CASE WHEN tgl = '2022-12-01' THEN score ELSE 0 END) AS 'Day 1'",
    "SUM(CASE WHEN tgl = '2022-12-02' THEN score ELSE 0 END) AS 'Day 2'",
    "SUM(CASE WHEN tgl = '2022-12-03' THEN score ELSE 0 END) AS 'Day 3'"
];

// 执行查询,按Name和月份分组
$scoreboard->select('Name')
           ->selectRaw(implode(', ', $selectFields))
           ->groupBy('Name', DB::raw('DATE_FORMAT(tgl, "%Y-%m")'));

场景2:对一组日期整体求和

如果需要把多个日期的score合并到一个字段统计,原逻辑本身是可行的,但必须补充GROUP BY才能得到分组后的总和:

$dateList = "'2022-12-01', '2022-12-02'";
$scoreboard->select('Name')
           ->selectRaw("SUM(CASE WHEN tgl IN ($dateList) THEN score ELSE 0 END) AS 'DecTotal'")
           ->groupBy('Name');

2. 相同AS别名的查询是否会累加

不会。分两种情况:

  • 同一select语句中重复使用相同别名:数据库会直接报错,因为字段名不允许重复。
  • 两次独立调用selectRaw设置相同别名:后一次的字段会覆盖前一次的,最终结果只保留最后一次的计算值,不会累加。

如果需要实现累加,需在同一个SUM函数中合并条件,或通过子查询、CTE先分别统计再相加。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:01:15