SQL-如何;过滤掉;具有1个以上身份的人

SQL-如何;过滤掉;具有1个以上身份的人,sql,impala,Sql,Impala,我试图在这里找到这个问题,但我可能不知道要搜索的确切术语 问题是: 我有这组客户(见图)。我只需要过滤那些状态为“user\u paused”或“interval\u paused”的。同一个客户id可能有多个状态,有时此状态可能为“活动”。如果是这样,这个客户不应该出现在我的最终结果中 请参见客户809-他不应该出现在我的最终结果中,因为他具有“活动”状态。所有其他的都很好,因为它们只有暂停状态 我仍然不知道如何从这里开始 非常感谢你 select * from table where cus

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

问题是:

我有这组客户(见图)。我只需要过滤那些状态为“user\u paused”或“interval\u paused”的。同一个客户id可能有多个状态,有时此状态可能为“活动”。如果是这样,这个客户不应该出现在我的最终结果中

请参见客户809-他不应该出现在我的最终结果中,因为他具有“活动”状态。所有其他的都很好,因为它们只有暂停状态

我仍然不知道如何从这里开始

非常感谢你

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

一种方法使用
分组方式和
拥有

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;

要排除任一列中“活动”的任何客户,请使用以下命令:

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

您可以很容易地找到所有状态为“活动”的客户:

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中有任何“活动”行的任何行


请注意,子查询并不总是最有效的解决方案-在某些情况下,子查询可能会使您的查询速度非常慢。

不确定是否需要区分,但这里有两种方法。我想这两种方法都可以在黑斑羚身上使用,但以防你有选择。第一种方法使用“左排除联接”(先进行联接,然后排除匹配的行),这使我们能够忽略活动状态客户。第二种方法使用更传统的“不存在”方法来删除具有活动状态的客户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 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”)可以在后续查询中重用,这确实是一个非常有用的特性


如果您想知道为什么我使用“MyCTE”作为名称,那么通常使用
创建的结构称为
公共表表达式(CTE)。

暂停状态状态和状态“活动”是否有效?您需要选择不同的结构,而不是每个状态一次?哦,我想我没有说清楚。我无法使用status active筛选出,因为我需要删除该特定客户的两个条目。因此,如图所示,客户809同时具有状态、间隔和活动。我需要删除这两个条目。如果我使用status active,它仍将返回一个条目。显示所需结果的示例所需结果将完全相同,但没有customer 809(两个条目都将被删除,因为对我来说,无论他有多少个暂停的条目,如果至少有一个处于活动状态,他都被视为处于活动状态)。我认为Impala不支持EXCEPT函数。我试过了,但是我错了。谢谢!我认为在这种情况下,这将非常有效。但问题是,我已经在使用两个子查询来获得您在图像中看到的结果。表格要比这复杂得多。@Kreiven-还有很多其他方法可以排除行。您还可以尝试将结果选择到临时表中,并从临时表中删除任何活动行的CustomerID。请在回答中添加更多说明:您更改了什么,与ops原始代码的差异在哪里,您为什么要进行更改,这有助于其他人理解为什么你的答案是一个真正的答案,为什么它现在起作用。谢谢
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')
;