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);

Мне нужно выбрать имена собак, для которых их соответствующие породы и возраст равны, поэтому вывод должен быть следующим:

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);

Однако я не понимаю, как преобразовать его в желаемый результат с двумя столбцами.

что вы хотите, если есть 3 или более одного возраста / породы? ряд для каждой пары?

ysth 25.01.2023 05:44

@ysth да, одна строка на пару

parsecer 25.01.2023 05:52
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
2
55
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Обычно это делается с помощью самостоятельного соединения:

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
имя1 имя2 А г Б Е

дбфиддл

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

Другие вопросы по теме