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

使用DENSE_RANK统计风格数后按CustomerName排序的SQL问题咨询

解决方案

根因说明

DENSE_RANK窗口函数的计算仅依赖其OVER子句内定义的排序规则,和外层查询的最终排序逻辑完全独立。你之前的写法是按StyleID排序生成累计值,而需求实际需要的是按CustomerName排序后,累计截止到当前客户的全局不同风格总数,两者排序基准不一致,因此结果不符合预期。

修改后SQL(兼容所有标准SQL数据库)

SELECT 
    c.CustomerName,
    ms.StyleName,
    ct.RunningTotal
FROM EntertainmentAgencyExample.Musical_Preferences mp
JOIN EntertainmentAgencyExample.Customers c USING (CustomerID)
JOIN EntertainmentAgencyExample.Musical_Styles ms USING (StyleID)
-- 关联每个客户对应的累计风格总数
JOIN (
    SELECT 
        CustomerName,
        SUM(AddStyleCnt) OVER (ORDER BY CustomerName ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningTotal
    FROM (
        -- 统计每个客户新增的未在更早客户中出现过的风格数量
        SELECT 
            c.CustomerName,
            COUNT(DISTINCT CASE WHEN c.CustomerName = t.FirstCusOfStyle THEN ms.StyleID END) AS AddStyleCnt
        FROM EntertainmentAgencyExample.Musical_Preferences mp
        JOIN EntertainmentAgencyExample.Customers c USING (CustomerID)
        JOIN EntertainmentAgencyExample.Musical_Styles ms USING (StyleID)
        -- 关联每个风格首次出现的客户名称
        JOIN (
            SELECT 
                StyleID,
                MIN(c2.CustomerName) AS FirstCusOfStyle
            FROM EntertainmentAgencyExample.Musical_Preferences mp2
            JOIN EntertainmentAgencyExample.Customers c2 USING (CustomerID)
            GROUP BY StyleID
        ) t USING (StyleID)
        GROUP BY c.CustomerName
    ) cus_add
) ct USING (CustomerName)
ORDER BY c.CustomerName ASC;

逻辑说明

  1. 最内层子查询先计算每个音乐风格首次出现的客户名称,作为判断风格是否为当前客户新增的依据
  2. 中间层统计每个客户新增的风格数量,仅统计首次出现在当前客户的风格
  3. 外层按客户名称排序,累计计算截止到每个客户的全局不同风格总数,关联回原始数据后按客户名称排序,即可得到和预期完全一致的结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:45:04