Мне нужна помощь с возвратом строк, которые имеют общие значения в одном из столбцов. Формат данных следующий:
Таблица (Люди) - Имена всех Участников
* ID * Name *
------------------
* 1 * Alice *
* 2 * Bruce *
* 3 * Charlie *
* 4 * Dan *
* 5 * Eric *
* 6 * Fannie *
Таблица (список) - список участников каждого мероприятия
* Txn * Event_ID * ID *
-----------------------
* T1 * A * 1 *
* T2 * A * 2 *
* T3 * A * 3 *
* T4 * A * 4 *
* T5 * B * 1 *
* T6 * B * 2 *
* T7 * B * 5 *
* T8 * B * 6 *
Я хотел бы выяснить, (i) встречались ли ранее какие-либо два человека друг с другом, и если да, то (ii) на каком событии. В данном случае мне интересно узнать, встречались ли раньше Участник 1 и Участник 2, желаемый результат:
* Event_ID * ID * Name * Txn *
---------------------------------
* A * 1 * Alice * T1 *
* A * 2 * Bruce * T2 *
* B * 1 * Alice * T5 *
* B * 2 * Bruce * T6 *
Это код, который я придумал до сих пор:
SELECT EVENT_ID, Txn
FROM People
JOIN List ON People.ID=List.ID
WHERE (List.ID=1 OR List.ID=2)
Group BY TXN, EVENT_ID
В настоящее время он возвращает только все события, в которых приняли участие Участник 1 и Участник 2. Я думаю, что мне нужно выполнить дальнейшую сортировку по группам и количеству, но я не уверен, как это следует включить в код.
GROUP BY EVENT_ID, HAVING COUNT (EVENT_ID)>1






Если вы хотите знать это только для двух человек, вы можете в качестве альтернативы вернуть одну строку с двумя людьми в ней. Конечно, это не очень хорошо масштабируется, если вы хотите расширить охват большего количества людей:
select
a1.Event_ID,
a1.Txn as Txn1,
a2.Txn as Txn2,
p1.ID as ID1,
p1.Name as Name1,
p2.ID as ID2,
p2.Name as Name2
from
List a1
inner join List a2
on a2.Event_ID = a1.Event_ID
and a2.Id <> a1.Id
inner join People p1 on p1.ID = a1.ID
inner join People p2 on p2.ID = a2.ID
where
p1.ID = 1 and p2.ID = 2
Вам вообще не нужна группировка, вам просто нужно соединить таблицу с самой собой.
SELECT
*
FROM list l1
JOIN list l2 ON l1.ID != l2.ID AND l1.Event_ID = l2.Event_ID
WHERE
1 IN (l1.ID, l2.ID)
AND 2 IN (l1.ID, l2.ID)
Это может быть проблема фронтенда. В любом случае, порядок столбцов не должен беспокоить. Ваш код читает результат и заботится о представлении. База данных не должна этого делать.
Хорошо, у меня просто возникла идея, что, возможно, вы ищете события, в которых люди встречались друг с другом, то есть, а не события, в которых был только один человек (что было недостатком в моем предыдущем коде, см. ниже). Это работает, чтобы найти только события, на которых присутствовали два человека:
select l.event_id, p.id as person_id, p.name as person_name, l.txn as txn_id
from people p
inner join list l
on p.id=l.person_id
inner join
(
select event_id, count(*) as headcount
from list
group by event_id
) x
on l.event_id=x.event_id
where x.headcount > 1
group by l.event_id, p.id, p.name
Я думаю, вам нужно это:
select l.event_id, p.id as person_id, p.name as person_name, l.txn as txn_id
from people p
inner join list l
on p.id=l.person_id
group by l.event_id, p.id, p.name
Результат:
# event_id, person_id, person_name, txn_id
'A', '1', 'Alice', 'T1'
'A', '2', 'Bruce', 'T2'
'A', '3', 'Charlie', 'T3'
'A', '4', 'Dan', 'T4'
'B', '1', 'Alice', 'T5'
'B', '2', 'Bruce', 'T6'
'B', '5', 'Eric', 'T7'
'B', '6', 'Fannie', 'T8'
Я использовал имя столбца как «person_id» в таблице списка, чтобы избежать путаницы со столбцом «id» в таблице person. Кроме того, я полагаю, что id — это первичный ключ, а автоматический идентификатор в таблице списка, а «person_id» — это идентификатор ссылки на внешний ключ из таблицы person.
Можно ли показать работу SQLfiddle? Не очень хорошо знаком с различными обозначениями
обновленный: db-fiddle.com/f/qzbg9GJ8q5riehPwYfpY2n/…
Основываясь на различных ответах, следующий код наиболее близок к тому, что я искал.
Единственная небольшая проблема заключается в том, что я не мог получить выходные столбцы в том порядке, в котором я изначально искал. Мелкие неудобства.
SELECT l1.Event_ID, l1.ID, p.Name, l1.Txn
FROM list l1
JOIN list l2 ON l1.ID != l2.ID AND l1.Event_ID = l2.Event_ID
JOIN people p ON l1.ID = p.ID
WHERE
1 IN (l1.ID, l2.ID)
AND 2 IN (l1.ID, l2.ID)
ORDER BY l1.Event_ID, l1.ID;
См. код, работающий на dbfiddle
Спасибо. Я немного изменил ваши ответы, чтобы получить желаемый формат вывода. [ссылка]db-fiddle.com/f/xm48XeUkTdxp8SM8mL947n/0 У меня есть небольшая проблема: я не могу упорядочить выходные столбцы в нужном мне порядке (как указано выше).