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

SQL Server中如何基于另一列累计和阈值筛选指定列取值

报错原因

你写的SQL触发8120错误的核心原因是:子查询中同时使用了普通聚合函数SUM(CALLS_DROPS)和非聚合字段DEVICE_TYPE,但没有添加GROUP BY DEVICE_TYPE子句,SQL语法不允许未分组的普通聚合函数与非聚合字段混用。
另外你原有逻辑也和需求不匹配:

  • 窗口函数用了PARTITION BY DEVICE_TYPE,计算的是单个品牌的总消费,不是按降序排序后的累计消费和
  • 阈值系数错写为0.85,需求要求的是全量总分钟数的70%,对应系数0.7

正确实现方案

实现逻辑

  1. 先按设备品牌聚合,得到每个品牌的总消费分钟数,同时计算全量总消费的70%作为阈值
  2. 对聚合后的品牌按总消费分钟数降序排序,计算累加消费和
  3. 筛选出累加和小于等于阈值的所有品牌,再加上第一个让累加和超过阈值的品牌,刚好覆盖到70%的占比要求

可运行SQL(支持MySQL8.0+、SQL Server、PostgreSQL等所有支持窗口函数的数据库)

WITH brand_total AS (
    -- 按品牌汇总总消费,同时计算全量70%阈值
    SELECT 
        设备品牌 AS device_type,
        SUM(总消费分钟数) AS total_minutes,
        SUM(SUM(总消费分钟数)) OVER() * 0.7 AS cutoff
    FROM 你的业务表名 -- 替换成你实际的表名即可
    GROUP BY 设备品牌
),
running_calculate AS (
    -- 按总消费降序排序,计算累计消费
    SELECT 
        device_type,
        total_minutes,
        cutoff,
        SUM(total_minutes) OVER(ORDER BY total_minutes DESC) AS accumulate_total
    FROM brand_total
)
-- 筛选符合要求的头部品牌
SELECT device_type
FROM running_calculate
WHERE accumulate_total <= cutoff 
OR (accumulate_total > cutoff AND accumulate_total - total_minutes <= cutoff)

拿你给出的示例数据验证:全量总消费72,70%阈值为50.4,聚合后苹果总消费32、三星22、华为17,累加后苹果32≤50.4,三星累加后为54>50.4且减去自身后的32≤50.4,所以最终返回Apple、Samsung两个品牌,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:06:03