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

MySQL问题:将GROUP BY筛选的同品种同年龄狗名转为双列输出

如何将同品种同年龄的狗名转换为双列输出

已知dogs表结构:

create table dogs (name char(10), breed char(20), age int);

插入数据:

insert into dogs (name, breed, age) values ('A', 'Breed 1', 1);
insert into dogs (name, breed, age) values ('B', 'Breed 2', 2);
insert into dogs (name, breed, age) values ('C', 'Breed 3', 3);
insert into dogs (name, breed, age) values ('D', 'Breed 1', 4);
insert into dogs (name, breed, age) values ('E', 'Breed 2', 2);
insert into dogs (name, breed, age) values ('F', 'Breed 3', 5);
insert into dogs (name, breed, age) values ('G', 'Breed 1', 1);

需求是筛选出品种(breed)和年龄(age)均相同的狗,将名字分别放在name1和name2列输出,预期结果:

name1    name2
A        G
B        E

你当前的查询能筛选出符合条件的狗名,但要实现双列格式,可采用以下两种方法:

方法1:自连接实现配对

直接通过自连接匹配同品种、同年龄且名字不同的记录,同时用d1.name < d2.name避免重复配对(比如不会同时出现A-G和G-A):

SELECT d1.name AS name1, d2.name AS name2
FROM dogs d1
JOIN dogs d2 
  ON d1.breed = d2.breed 
  AND d1.age = d2.age 
  AND d1.name < d2.name;

执行后会直接得到预期结果。

方法2:窗口函数+条件聚合

如果后续可能出现同品种同年龄的狗多于2只的情况,这种方法扩展性更强:

WITH ranked_dogs AS (
  SELECT 
    name, 
    breed, 
    age,
    -- 按品种、年龄分组,给组内名字排序编号
    ROW_NUMBER() OVER(PARTITION BY breed, age ORDER BY name) AS rn
  FROM dogs
  -- 先筛选出存在重复品种+年龄的记录
  WHERE (breed, age) IN (
    SELECT breed, age 
    FROM dogs 
    GROUP BY breed, age 
    HAVING COUNT(*) > 1
  )
)
-- 按品种、年龄分组,将不同编号的名字映射到对应列
SELECT 
  MAX(CASE WHEN rn = 1 THEN name END) AS name1,
  MAX(CASE WHEN rn = 2 THEN name END) AS name2
FROM ranked_dogs
GROUP BY breed, age;

该方法通过窗口函数给每组内的狗名编号,再用条件聚合将编号1和2的名字分别放入name1和name2列,即使某组有更多狗,也能按顺序提取对应名字。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:55:24