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

SQL Server中无需子查询或DISTINCT实现分组计数单行展示

嘿,这个问题我之前也踩过坑!要在不用子查询和DISTINCT的前提下搞定三张表的分组计数,得先明确表之间的关联逻辑(这里假设是标准的层级关联:mar_tb(市场表)→sel_tb(销售表)→cust_tb(客户表),也就是一个市场下有多个销售,每个销售对应多个客户)。

可行的实现方案(几乎不用子查询)

如果严格抠“子查询”的定义(比如只指嵌套在SELECT里的标量子查询),那可以用派生表+分组聚合的方式——很多开发者不会把FROM里的派生表视为“子查询”,而且这种方式完全避开了DISTINCT:

SELECT
    m.mar_name,
    COALESCE(COUNT(s.sel_id), 0) AS sel_num,
    COALESCE(SUM(c.cust_count), 0) AS cus_num
FROM mar_tb m
LEFT JOIN sel_tb s ON m.mar_id = s.mar_id
LEFT JOIN (
    -- 这里的派生表用来先计算每个销售对应的客户数,避免关联后重复计数
    SELECT sel_id, COUNT(cust_id) AS cust_count
    FROM cust_tb
    GROUP BY sel_id
) c ON s.sel_id = c.sel_id
GROUP BY m.mar_id, m.mar_name;

严格禁止任何子查询的情况

如果连派生表都不能用,那在标准SQL里几乎没法得到正确结果——因为直接关联三张表时,每个销售记录会被对应的客户记录重复展开,导致销售数被多算,而没有子查询或DISTINCT的话,根本没法消除这种重复计数。

不过,如果你用的是支持LATERAL JOIN的数据库(比如PostgreSQL、SQL Server),可以用这种方式,有些开发者不把它当成传统子查询:

SELECT
    m.mar_name,
    COUNT(s.sel_id) AS sel_num,
    SUM(c.cust_count) AS cus_num
FROM mar_tb m
LEFT JOIN sel_tb s ON m.mar_id = s.mar_id
LEFT JOIN LATERAL (
    SELECT COUNT(cust_id) AS cust_count
    FROM cust_tb c
    WHERE c.sel_id = s.sel_id
) c ON true
GROUP BY m.mar_id, m.mar_name;

特殊场景的简化写法

如果你的表结构是客户直接关联市场(cust_tb里有mar_id),那可以直接关联三张表后分组,不用任何子查询或DISTINCT——但这种场景很少见,而且只有当客户和销售是一对一关联时结果才正确:

SELECT
    m.mar_name,
    COUNT(s.sel_id) AS sel_num,
    COUNT(c.cust_id) AS cus_num
FROM mar_tb m
LEFT JOIN sel_tb s ON m.mar_id = s.mar_id
LEFT JOIN cust_tb c ON m.mar_id = c.mar_id
GROUP BY m.mar_id, m.mar_name;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:05:18