У меня есть таблица 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);
Мне нужно выбрать имена собак, для которых их соответствующие породы и возраст равны, поэтому вывод должен быть следующим:
name1 name2
A G
B E
потому что собаки A и G принадлежат к одной породе (Порода 1) и возрасту (1), а собаки B и E относятся к одной породе (Порода 2) и возрасту (2).
Я знаю, как узнать имена собак, которые должны быть в выводе:
select name from dogs where (breed, age) in (select breed, age from (select breed, age, count(*) as n from dogs group by breed, age having n > 1) as a);
Однако я не понимаю, как преобразовать его в желаемый результат с двумя столбцами.
@ysth да, одна строка на пару






Обычно это делается с помощью самостоятельного соединения:
select D1.name, D2.name
from dogs d1
inner join
dogs d2
on d1.breed=d2.breed
and d1.age=d2.age
and d1.name<d2.name
d1.name>d2.name служит двум целям: 1. предотвратить совпадение строки с самой собой и 2. убедиться, что мы получаем только одну строку на пару (не (A,G) и (G,A), например).
ИспользуйтеGROUP_CONCAT(), чтобы различать разные имена
select
GROUP_CONCAT(distinct name) name
from dogs
group by
breed
,age
having GROUP_CONCAT(name) like '%,%'
результат
затем используйте SUBSTRING_INDEX и subquery, чтобы изменить приведенный выше результат на столбцы
SELECT
SUBSTRING_INDEX(Name, ',', 1) name1
,SUBSTRING_INDEX(Name, ',', -1) name2
From(
select
GROUP_CONCAT(distinct name) Name
from dogs
group by
breed
,age
having GROUP_CONCAT(name) like '%,%') a
SELECT
d1.name,d1.breed, d1.age, d2.name, d2.breed, d2.age
FROM dogs d1
JOIN dogs d2
ON d1.breed=d2.breed AND d1.age = d2.age AND d1.name != d2.name
что вы хотите, если есть 3 или более одного возраста / породы? ряд для каждой пары?