分组依次,然后只选择布尔列的每个值都为真的记录

时间:2018-01-26 16:57:37

标签: sql postgresql

我有MS SQL数据库和postgres数据库。任何一种解决方案都可行,因为我可以翻译它。

我们有一个customer_phone表,相关的列是:

id, customer_id, phone, is_bad

我需要做的是从此表中选择仅customer_id的所有is_bad = truein。因此,如果你有一个好的电话号码和一个坏的电话号码,你就不应该出现。

由于某些原因,我很难找到一种简单的方法来做到这一点,我觉得这应该看似简单。

这是一个开始,它至少让所有客户都知道他们的好坏数字,但我想知道是否有一种方法不必使用子查询和{{ 1}}' S?

select  customer_id, is_bad, count(customer_id)
from customer_phone cp
group by customer_id, is_bad
order by customer_id desc

4 个答案:

答案 0 :(得分:2)

您可以使用“聚合函数”bool_and

这需要一组输入和返回:

  

如果所有输入值都为true,则为true,否则为false

在您的情况下,我们希望每个is_bad对于特定客户都是真实的:

select customer_id
from customer_phone
group by customer_id
having bool_and(is_bad)

答案 1 :(得分:1)

您可以使用NOT EXISTS

select  customer_id
       ,is_bad
       ,count(customer_id)
from customer_phone cp
where not exists(select 1 from customer_phone 
                 where is_bad = true)
group by customer_id, is_bad
order by customer_id desc
;

答案 2 :(得分:1)

您可以使用MIN来确定是否只有is_bad值。你必须首先转向Int。

SELECT customer_id
FROM customer_phone cp
GROUP BY customer_id
HAVING MIN(cast(is_bad as int)) = 1;

答案 3 :(得分:1)

我发现在这样的布尔列上添加的最直观的方法是SUM一列1 TRUE0 FALSE 1}}:

CASE WHEN some_bool THEN 1 ELSE 0 END

所以在你的情况下:

SELECT id
FROM phones
GROUP BY id
HAVING
SUM(CASE WHEN NOT is_bad THEN 1 ELSE 0 END) = 0

查看this SQL fiddle,其中显示了正在运行的查询。