SQL:如何提取已执行操作A但从未执行操作B的客户ID?

时间:2018-10-08 18:06:44

标签: sql

这就是我需要吸引的:所有仅在线订购的客户(即客户1和3)。

考虑到表的结构方式(客户4在列表中出现两次),我正在努力从OMIT客户4的数据中获取数据,因为他们是在网上和实体店购买的。

数据:

客户1-在线购买

客户2-在商店购买

客户3-在线购买

客户4-在线购买

客户4-在商店购买

这是我的代码,我肯定仍能吸引到客户4,但不确定如何排除它们。当然,我正在使用的完整数据要大得多。

SELECT DISTINCT(table.customer_id)
FROM table
WHERE ((table.purchase_channel='store') 
    AND NOT (table.purchase_channel='online'))

3 个答案:

答案 0 :(得分:3)

我将使用条件聚合:

select t.customer_id
from t
group by t.customer_id
having sum(case when t.purchase_channel = 'store' then 1 else 0 end) > 0 and
       sum(case when t.purchase_channel = 'online' then 1 else 0 end) = 0;

我发现这种结构在多种情况下都很方便。对于您的特定条件,您可以将其缩短为:

select t.customer_id
from t
where t.purchase_channel in ('store', 'online')
group by t.customer_id
having min(t.purchase_channel) = 'store' ;

答案 1 :(得分:2)

使用“不存在”:

SELECT *
FROM table t
WHERE not exists(
   select 1 from table 
   where customer_id = t.customer_id 
    and  purchase_channel='online')

您应该尝试此处建议的所有变体。对于小表来说并不重要,但是对于大表则有很大的不同。例如。在Sql Server中,我发现“不存在”通常会生成最佳查询计划。确保您在(customer_id,purchase_channel)上具有索引。 在大型的分布式系统中,“不在”可能会更好。

答案 2 :(得分:0)

不使用

select customer_id from table t
     where   t.customer_id not in
    (
      SELECT table.customer_id
        FROM table
        WHERE  
            table.purchase_channel='online'
    ) and t.purchase_channel='store'