0

鉴于此架构和数据:

create table contacts (id int, name varchar(255));
create table events (id int, name varchar(255));
create table tickets (contact_id int, event_id int);

insert into contacts (id, name) values (1, 'Alice'), (2, 'Bob'), (3, 'Charlie');
insert into events (id, name) values (1, 'Event 1'), (2, 'Event 2');
insert into tickets (contact_id, event_id) values (1,1), (1,2);
insert into tickets (contact_id, event_id) values (2,2);

我如何找到只参加过一项活动的人?我希望只找到只参加过一次活动的 Bob,而不是参加过两次活动的 Alice,而不是参加过零次活动的 Charlie。

可能有数百个联系人和事件,我想找到之前未参加过任何事件的特定事件的联系人。

我在这个上画一个空白。

编辑:让我澄清一下,

我如何找到恰好参加过一项特定活动的人?对于活动 2,我希望只找到只参加过一项活动的 Bob,而不是参加过两次活动的 Alice,而不是参加过零次活动的 Charlie。

4

2 回答 2

1

@yang 的答案适用于仅参加过一个非特定活动的用户,但是,如果您想找到参加特定活动的用户作为他们的第一个也是唯一一个,如果tickets.event_id不能这样做,这将起作用NULL

SELECT t1.contact_id
FROM tickets t1
LEFT JOIN tickets t2
    ON t2.contact_id = t1.contact_id
    AND t2.event_id != t1.event_id
WHERE t1.event_id = 'someid'
    AND t2.event_id IS NULL;

(tickets.contact_id, tickets.event_id)假设有一个适当的索引以 提高性能..

于 2013-07-31T18:13:39.190 回答
0

这个版本的性能可能一样好,具体取决于您的优化器,并且意图是明确的(参加特定活动的所有联系人,但不参加任何其他活动):

SELECT *
FROM contacts c
WHERE EXISTS (SELECT * FROM tickets WHERE contact_id = c.id AND event_id = 2)
AND NOT EXISTS (SELECT * FROM tickets WHERE contact_id = c.id AND event_id <> 2)
于 2013-07-31T18:19:49.687 回答