SELECT
    name AS product_name,
    total_sales,
    RANK() OVER (
        PARTITION BY
            category
        ORDER BY
            total_sales DESC,
            product_id ASC
    ) AS category_rank
FROM 
    (SELECT
        p.name,
        p.product_id,
        SUM(quantity) AS total_sales,
        p.category
    FROM
        products p
    JOIN orders o ON o.product_id = p.product_id
    GROUP BY
        p.name,
        p.category,
        p.product_id
    ) AS subtable
ORDER BY
    category ASC, total_sales DESC
  1. 使用GROUP BY时,SELECT 语句中出现的字段,要么出现在 GROUP BY 中,要么被聚合(SUM, MAX等)处理。
  2. 使用LEFT JOIN时,右表有多行匹配时,左表行被复制对应组合
  3. 窗口函数 = 在行之间建立联系,不打乱原有行,给每行添加额外信息
  4. 窗口函数不能直接作用在 GROUP BY的结果上,除非用子查询包装一下。因为GROUP BY 是一次行聚合操作,改变了表的形状;窗口函数是行间计算,需要基于一张已经整理好的表来操作;所以必须先 GROUP BY,然后基于“结果表”用 OVER() 窗口。
  5. 窗口函数不能直接用在 WHERE 里,但可以在 SELECT、ORDER BY、HAVING 外层用。