基于foreign_key的百分比

时间:2019-01-08 16:02:11

标签: sql postgresql percentage

我有一个名为animals的表,该表具有以下列:

id: INT
state: VARCHAR

另一个称为house的表具有以下列:

id: INT
animal_id: INT
color: VARCHAR

我正在尝试获取动物(其状态为“活着”)及其ID在给定范围内,至少具有房屋(颜色为“红色”)的百分比。如果一只动物有一个以上的红房子,那没关系,应该只计算一次。

我知道在这种情况下如何获得动物数量:

SELECT COUNT(*)
FROM animals
WHERE state = 'living'
AND id IN (10,11,12)

我知道如何在这些条件下获得房屋:

SELECT COUNT(*)
FROM houses
WHERE color = 'red'

我不确定如何结合两个查询来获取一定比例的动物。

样本数据:

animals (id, state)

1, 'living'
2, 'dead'
3, 'living'
4, 'living'
5, 'dead'
6, 'living'


houses (id, animal_id, color)

1, 1, 'red'
2, 2, 'red'
3, 1, 'blue'
4, 6, 'red'
5, 4, 'red'
6, 1, 'red'  

我们希望将动物的范围缩小到ID为1、2、3和5的动物。

因此,由于id为2和5的动物已经死亡,因此不应将它们计入分母。现在,剩下的是动物1和3,但只有ID为1的动物有至少一间红房子(注意它有两个红房子,但我们不在乎),这意味着百分比是:

(1只具有至少一个阅读室的动物)/(2只正在生存的动物)= 50%

3 个答案:

答案 0 :(得分:1)

您可以使用LEFT JOIN来组合表格。然后AVG()可用于获取所需的比率:

SELECT AVG( (h.color = 'red')::int ) as ratio_red
FROM animals a LEFT JOIN
     houses h
     ON a.id = h.animal_id
WHERE a.state = 'living'
      a.id IN (10, 11, 12);

对于修改后的计算,您可以使用:

SELECT COUNT(DISTINCT CASE WHEN h.color = 'red' THEN h.animal_id END) / COUNT(DISTINCT a.id) as ratio_red
FROM animals a LEFT JOIN
     houses h
     ON a.id = h.animal_id
WHERE a.state = 'living'
      a.id IN (10, 11, 12);

答案 1 :(得分:1)

通过EXISTS运算符,您可以检查动物是否至少有一个红房子,而不必担心JOIN的结果重复。将其用作CASE WHEN分组函数中AVG的条件应返回预期结果。

这是(未经测试的)查询

SELECT AVG(CASE WHEN exists(SELECT id
                            FROM houses
                            WHERE color = 'red' and animal_id = a.id
                            LIMIT 1) 
                THEN 100.0 ELSE 0.0 END)
FROM animals a
WHERE a.state = 'living' 
AND a.id IN (10,11,12)

答案 2 :(得分:0)

选择动物id,颜色,住所t1 内部联接(从id中的动物组中选择id,count(*)作为生活对象)t2 在t1.animalid = t2.id上,其中color ='red'