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

SQL多表关联统计各州对应水果总数量问题求助

数据库SQL查询问题

现有表结构及测试数据

-- PAR表:人员信息表
CREATE TABLE PAR (
    ID          varchar(10) not null,
    Name                varchar(20) not null,
    State               varchar(20) not null,
    primary key (ID)
);

INSERT INTO PAR (ID, Name, State)
VALUES
('A000','Susan','New York'),
('B123','Bob','Texas'),
('C456','Tony','Washington'),
('D789','Adam','California');

-- GROUP表:群组信息表,存储每个群组的成员ID(GROUP为SQL关键字,使用反引号转义)
CREATE TABLE `GROUP` (
    GroupID         varchar(25) not null,
    Person1         varchar(15) not null,
    Person2         varchar(15) not null,
    Person3         varchar(15),
    Person4         varchar(15),
    primary key (GroupID)
);

INSERT INTO `GROUP` (GroupID, Person1, Person2, Person3, Person4)
VALUES
('G234','A000','B666','C777'),
('G456','B123','D898','E632'),
('G789','C456', null, null),
('G444','D789','O123', null);

-- SOLO表:个人水果关联表
CREATE TABLE SOLO (
    Classification          varchar(15) not null,
    ID      varchar(10) not null,
    Fruits          varchar(10) not null,
    primary key (Classification, ID),
    foreign key (ID) references PAR(ID)
);

INSERT INTO SOLO(Classification, ID, Fruits)
VALUES
('A Group','A000','Apple'),
('A Group','B123','Banana'),
('B Group','C456','Orange');

-- GROUPINGS表:群组水果关联表
CREATE TABLE GROUPINGS (
    Classification      varchar(20) not null,
    `Group`           varchar(25) not null,
    Fruits          varchar(15) not null,
    primary key (Classification, `Group`),
    foreign key (`Group`) references `GROUP`(GroupID)
);

INSERT INTO GROUPINGS(Classification, `Group`, Fruits)
VALUES
('A Group','G234','Apple'),
('B Group','G456','Grape'),
('A Group','G789','Banana'),
('D Group','G444','Orange');

预期查询结果

State     |  Fruits
----------+-------
New York  | 2
Texas     | 2
Washington| 2
California| 1

问题说明

原始查询逻辑有误,需要实现的统计规则为:统计每个州对应的水果总数,总数由两部分组成:

  • 该州所有人员在SOLO表中关联的水果记录数
  • 该州所有人员作为群组成员时,所属群组在GROUPINGS表中关联的水果记录数
    核心难点是如何将PAR表的人员ID与GROUP表中Person1/Person2/Person3/Person4四个成员列做关联。

正确实现SQL

SELECT 
    p.State,
    IFNULL(solo_cnt, 0) + IFNULL(group_cnt, 0) AS Fruits
FROM PAR p
-- 统计每个人对应的SOLO水果数量
LEFT JOIN (
    SELECT ID, COUNT(*) AS solo_cnt
    FROM SOLO
    GROUP BY ID
) s ON p.ID = s.ID
-- 统计每个人所属群组对应的水果数量
LEFT JOIN (
    SELECT person_id, COUNT(*) AS group_cnt
    FROM (
        -- 将4个成员列拆分为单列行数据,解决多列关联问题
        SELECT Person1 AS person_id, GroupID FROM `GROUP`
        UNION ALL
        SELECT Person2 AS person_id, GroupID FROM `GROUP`
        UNION ALL
        SELECT Person3 AS person_id, GroupID FROM `GROUP`
        UNION ALL
        SELECT Person4 AS person_id, GroupID FROM `GROUP`
    ) t
    WHERE t.person_id IS NOT NULL
    JOIN GROUPINGS g ON t.GroupID = g.`Group`
    GROUP BY t.person_id
) g ON p.ID = g.person_id
GROUP BY p.State
ORDER BY p.State;

逻辑说明

  1. 先通过子查询按人员ID聚合,统计每个人在SOLO表中的水果记录数
  2. 通过UNION ALL把GROUP表的4个成员列拆为<人员ID, 群组ID>的行结构,解决多成员列无法直接关联的问题
  3. 将拆分后的群组人员数据和GROUPINGS表关联,统计每个人所属群组对应的水果记录数
  4. 把两部分统计结果左连接到PAR表,按州聚合求和即可得到预期结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:15:09