SQL - 如何"过滤掉"拥有超过1个身份的人

时间:2017-11-09 16:16:19

标签: sql impala

我试图在这里找到这个问题,但我可能并不知道要搜索的确切术语。

问题在于:

我有这组客户(见图)。我只需要过滤那些状态为" user_paused"或" interval_paused"。同一个customer_id可能具有多于1个状态,有时,此状态可以是"活动"。如果是这样,该客户不应出现在我的最终结果中。

见客户809 - 他不应该出现在我的最终结果中,因为他有一个"活跃的"状态。所有其他人都很好,因为他们只有暂停的状态。

我仍然无法弄清楚如何从这里开始。

非常感谢你。

IMAGE HERE!

6 个答案:

答案 0 :(得分:1)

SELECT DISTINCT  customer_id FROM TABLE
WHERE status IN ( 'user_paused','interval_paused')
EXCEPT
SELECT DISTINCT  customer_id FROM TABLE
WHERE status = 'active'

答案 1 :(得分:0)

select * from table
where customer_id in 
(select customer_id from table 
where status in ('interval_paused','user_paused') )

答案 2 :(得分:0)

一种方法使用group byhaving

select customer_id
from t
group by customer_id
having sum(case when status not in ('user_paused', 'interval_paused') then 1 else 0 end) = 0;

答案 3 :(得分:0)

要在任一列中排除任何“有效”的客户,请使用以下内容:

select * from customers 
where paused_statuses != 'active'
and status != 'active';

答案 4 :(得分:0)

您可以非常轻松地找到状态为“活跃”的所有客户:

SELECT customerid FROM table WHERE status = 'active'

如果您希望从结果中排除任何客户(如果他们有活动行),您可以在子查询中执行此操作:

SELECT * FROM table WHERE /* your other query restrictions */
AND customerID NOT IN
(
    SELECT customerid FROM table WHERE status = 'active'
)

这将允许您消除任何具有任何“活动”行的customerid的行。

请注意,子查询并不总是最有效的解决方案 - 可能存在子查询会使查询速度变慢的情况。

答案 5 :(得分:0)

不确定您是否需要区分,但这里有两种方法。我认为两者都适用于Impala,但万一你有选择权。第一个使用“左排除连接”(使连接然后排除匹配的行),这使我们能够忽略活动状态客户。第二种方法使用更传统的“不存在”方法来删除具有活动状态的customer_id。

select /* distinct */ t1.customer_id 
from table t1
left join table t2 on  t1.customer_id = t2.customer_id and t2.status = 'active'
where t2.customer_id IS NULL
and t1.status in ('interval_paused','user_paused')
;

select /* distinct */ t1.customer_id 
from table t1
where t1.status in ('interval_paused','user_paused')
and NOT EXISTS (
     select null
     from table t2
     where t1.customer_id = t2.customer_id
     and t2.status = 'active'
     )
;

如果您现有的查询很复杂,那么为了简化这些添加,请使用WITH clause,如下所示:

WITH MyCTE AS (

    -- place the whole existing query here

)
select /* distinct */ t1.customer_id 
from MyCTE t1
left join MyCTE t2 on  t1.customer_id = t2.customer_id and t2.status = 'active'
where t2.customer_id IS NULL
and t1.status in ('interval_paused','user_paused')
;

请注意,您提供的名称(“MyCTE”)可以在后续查询中重复使用 - 这确实是一个非常有用的功能。

一般情况下,WITH创建的结构称为common table expressions(CTE),如果您想知道为什么我使用“MyCTE”作为名称。