【问题标题】:SQL: how to find people that have attended only one eventSQL:如何找到只参加过一次活动的人
【发布时间】:2013-08-01 02:24:07
【问题描述】:

鉴于此架构和数据:

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。

【问题讨论】:

    标签: mysql sql join


    【解决方案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) 上有一个适当的索引以提高性能..

    【讨论】:

      【解决方案2】:

      根据您的优化器,此版本的性能可能会一样好,并且意图是明确的(参加特定活动的所有联系人,但不参加任何其他活动):

      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)
      

      【讨论】:

        猜你喜欢
        • 2015-02-26
        • 2020-09-05
        • 2021-11-06
        • 2020-02-23
        • 2021-12-19
        • 1970-01-01
        • 2013-09-07
        • 2021-07-04
        • 2021-07-07
        相关资源
        最近更新 更多