Вопрос SQL.Найдите двух человек с одинаковыми увлечениями за одним столом - PullRequest
0 голосов
/ 24 сентября 2018

TABLE [tbl_hobby]

person_id (int), hobby_id (int)

имеет много записей.Я хочу получить SQL-запрос, чтобы найти все пары personid, которые имеют одинаковые хобби (один и тот же hobby_id).

Если A имеет hobby_id 1, B тоже, если A не имеет hobby_id 2, B не делаеттоже, мы будем выводить person_ids A & B.

Если A и B и C достигают пределов, мы выводим A & B, B & C, A & C.

Я закончил очень-очень-очень глупым методом: множественные объединения самой таблицы и несколько подзапросов.И, конечно, насмехается над лидером.

Есть ли какой-либо высокопроизводительный метод в SQL для этого вопроса?

Я много думал об этом с 36 часов назад ......


пример данных в дампе MySQL

CREATE TABLE `tbl_hobby` (
  `person_id` int(11) NOT NULL,
  `hobby_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `tbl_hobby` (`person_id`, `hobby_id`) VALUES
(1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(2, 2),
(2, 3),(2, 4),(3, 1),(3, 2),(3, 3),(3, 4),
(4, 1),(4, 3),(4, 4),(5, 1),(5, 5),(5, 9),
(6, 2),(6, 3),(6, 4),(7, 1),(7, 3),(7, 7),
(8, 2),(8, 3),(8, 4),(9, 1),(9, 2),(9, 3),
(9, 4),(10, 1),(10, 5),(10, 9),(10, 11);
COMMIT;

Экспертный результат: (2 и 6 и 8 одинаковые, 3 и 9 одинаковые)

2,6
2,8
6,8
3,9

ПорядокРезультат записи и порядок двух чисел в одной записи не важен.Все записи результатов в одном или двух столбцах принимаются, поскольку их легко объединять или разделять.

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Альтернативная версия, без использования какой-либо проприетарной обработки строк:

select distinct t1.person_id, t2.person_id
from tbl_hobby t1
join tbl_hobby t2
  on t1.person_id < t2.person_id
where 2 = all (select count(*)
               from tbl_hobby 
               where person_id in (t1.person_id, t2.person_id)
               group by hobby_id);

Возможно, менее эффективный, но переносимый!

0 голосов
/ 24 сентября 2018

Совокупность на человека, чтобы получить ряды своих хобби.Затем составьте список по хобби, чтобы узнать, кто принадлежит более чем одному человеку.

select hobbies, group_concat(person_id order by person_id) as persons
from
(
  select person_id, group_concat(hobby_id order by hobby_id) as hobbies
  from tbl_hobby
  group by person_id
) persons
group by hobbies
having count(*) > 1
order by hobbies;

Это дает список людей на хобби.Какой самый простой способ вывести решение, так как в противном случае нам пришлось бы построить все возможные пары.

ОБНОВЛЕНИЕ: Если вам нужны пары, вам придется запросить таблицу дважды:

select p1.person_id as person 1, p2.person_id as person2
from
(
  select person_id, group_concat(hobby_id order by hobby_id) as hobbies
  from tbl_hobby
  group by person_id
) p1
join
(
  select person_id, group_concat(hobby_id order by hobby_id) as hobbies
  from tbl_hobby
  group by person_id
) p2 on p2.person_id > p1.person_id and p2.hobbies = p1.hobbies
order by person1, person2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...