我有没有办法提取只包含sql中某些值的数据?

时间:2014-06-04 01:45:38

标签: sql

我是否有方法提取仅包含特定值的数据。 例如:

Contact    Asset       Status
AB       1       Cancelled
AB       2       Cancelled
AB       3       Cancelled
AB       4       Cancelled
CD       5       Cancelled
CD       6       Active
CD       7       Cancelled
CD       8       Active

我想要的只是那些仅包含已取消资产的联系人(如联系人AB)。而不是那些同时取消和活动资产的人(如联系人CD)。

3 个答案:

答案 0 :(得分:1)

您可以使用group byhaving子句执行此操作:

select contact
from table t
group by contact
having min(status) = 'Cancelled' and max(status) = 'Cancelled';

这适用于您示例中的数据。如果status可能是NULL,并且您想将其计为不同的值,则逻辑会稍微复杂一些。

答案 1 :(得分:0)

纯粹的关系逻辑方式更容易理解,但性能较差,需要某种连接才能工作。让我们满足条件

  1. 每个Cancelled
  2. 至少有一个状态Contact
  3. 但同一Contact的{​​{1}}有0种状态,不是Cancelled
  4. 像这样的查询中的

    SELECT DISTINCT
       CS.Contact
    FROM
       ContactStatus CS
    WHERE
       CS.Status = 'Cancelled' -- at least one cancelled
       AND NOT EXISTS ( -- but there are none of...
          SELECT *
          FROM ContactStatus CS2 -- contacts in the same table
          WHERE
             CS.Contact = CS2.Contact -- for that same contact
             AND CS.Status <> 'Cancelled' -- that aren't cancelled
       )
    ;
    

    但是我们可以使用聚合来做到这一点,通过一点点思考,只需要对表进行一次扫描:

    SELECT
       Contact
    FROM
       ContactStatus
    GROUP BY
       Contact
    HAVING
       Count(*) = Count(CASE WHEN Status = 'Cancelled' THEN 1 END)
    ;
    

    HAVING子句中的其他聚合表达式是可能的,例如:

    Count(CASE WHEN Status <> 'Cancelled' THEN 1 END) = 0 -- or Min()
    Min(Status) = 'Cancelled' AND Max(Status) = 'Cancelled'
    Max(CASE WHEN Status = 'Cancelled' THEN 0 ELSE 1 END) = 0
    Sum(SELECT 1 WHERE Status <> 'Cancelled') = 0
    

    在这种情况下,所有这些都可以解决问题;选择对你最有意义的那个。

答案 2 :(得分:-1)

Select contact from contacts a
where a.status = 'Canceled' AND contact = 'AB'