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

关联含重复gid的表时,如何保持左表行数并输出唯一gid结果

解决单gid对应多name时的唯一输出问题

问题背景

现有两张表:

table1(费用表)

id gid   cost
1  1000  123 
2  2000  123 
3  1000  111 
4  3000  222
5  1000  333

table2(名称表,现支持单gid对应多name)

id gid   name      feature
1  1000  AAA       xxx
2  2000  BBB  
3  3000  CCC
4  4000  DDD
5  2000  NewName   yyy

需要输出唯一gid,对应table1的总费用totalCost;若table2中同一gid绑定多个name,仅保留其中一个,期望结果:

gid  name    totalCost
1000 AAA     567  -- 123+111+333=567
2000 BBB     123
3000 CCC     222

解决方案

方法1:窗口函数筛选指定优先级的name

通过ROW_NUMBER()给每个gid下的记录排序,仅保留排序后的第一条(可自定义排序规则,比如保留最早录入的name):

WITH table2_unique AS (
    SELECT gid, name,
           ROW_NUMBER() OVER (PARTITION BY gid ORDER BY id) AS rn  -- 按table2的id排序,保留最早的name
    FROM table2
)
SELECT a.gid, b.name, a.totalCost
FROM (
    SELECT gid, SUM(cost) AS totalCost
    FROM table1
    GROUP BY gid
) a
LEFT JOIN (
    SELECT gid, name FROM table2_unique WHERE rn = 1
) b ON a.gid = b.gid;

若想保留字典序最小的name,将ORDER BY id改为ORDER BY name即可。

方法2:聚合函数取任意唯一name

如果不需要指定保留哪一个name,仅需保证唯一,可直接用MIN()/MAX()聚合table2的name:

SELECT a.gid, b.name, a.totalCost
FROM (
    SELECT gid, SUM(cost) AS totalCost
    FROM table1
    GROUP BY gid
) a
LEFT JOIN (
    SELECT gid, MIN(name) AS name  -- 取字典序最小的name,用MAX则取最大的
    FROM table2
    GROUP BY gid
) b ON a.gid = b.gid;

方法3:子查询直接取单条name(简洁写法)

在关联时通过子查询直接获取每个gid的一条name记录,注意不同数据库的语法差异:

-- MySQL/PostgreSQL 写法
SELECT a.gid, 
       (SELECT name FROM table2 WHERE gid = a.gid LIMIT 1) AS name,
       a.totalCost
FROM (
    SELECT gid, SUM(cost) AS totalCost
    FROM table1
    GROUP BY gid
) a;

-- SQL Server 写法(替换LIMIT 1为TOP 1)
SELECT a.gid, 
       (SELECT TOP 1 name FROM table2 WHERE gid = a.gid) AS name,
       a.totalCost
FROM (
    SELECT gid, SUM(cost) AS totalCost
    FROM table1
    GROUP BY gid
) a;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:16:07