计算PostgreSQL中枚举的所有值

时间:2018-12-27 11:23:20

标签: sql postgresql enums group-by count

我有一个名为users的表,该表包含以下列:

id: INT NOT NULL
face: face_type

face_type是一个ENUM类型,具有以下值:'square''round''triangle'

还有另一个名为houses的表,该表具有以下列:

id: INT NOT NULL
user_id: INT NOT NULL

现在,我想按不同类型的面孔类型对所有房屋进行分组。所以,到目前为止,我是这样的:

SELECT users.face_type, COUNT(*)
FROM users
LEFT JOIN houses ON houses.user_id = users.id
GROUP BY users.face_type

问题是我还想获取face_type的所有用户都没有的行,以及NULL face_type的结果。因此,例如,如果我有以下数据:

users (id, face_type)

1, 'round'
2, 'triangle'

houses (id, user_id)
1, 1
2, 1
3, 2

我希望结果是:

face_type, count
'round'          2
'triangle'       1
'square'         0
null             0

我知道如何通过执行以下操作来获得face_type枚举的所有潜在值:

SELECT unnest(enum_range(NULL::face_type)) AS face_types;

但是我不知道如何使用它来计算聚合中所有潜在的面孔类型,以及计算NULL面孔类型。

3 个答案:

答案 0 :(得分:1)

您可以使用LEFT JOIN

SELECT ft.face_type, COUNT(h.user_id)
FROM (SELECT unnest(enum_range(NULL::face_type)) AS face_types
     ) ft LEFT JOIN
     users u
     ON u.face_type = ft.face_type LEFT JOIN
     houses h
     ON h.user_id = u.id
GROUP BY ft.face_type;

要获取NULL,只需使用UNION ALL

SELECT ft.face_type, COUNT(h.user_id)
FROM (SELECT unnest(enum_range(NULL::face_type)) AS face_types
      UNION ALL
      SELECT NULL
     ) ft LEFT JOIN
     users u
     ON u.face_type = ft.face_type LEFT JOIN
     houses h
     ON h.user_id = u.id
GROUP BY ft.face_type;

当然,=不会每次匹配。如果可能的话,那么您想将JOIN条件更改为u.face_type is not distinct from ft.face_type

答案 1 :(得分:0)

到COUNT(房子。*)

SELECT face_type.type, COUNT(houses.*)
FROM (SELECT unnest(enum_range(NULL::face_type))) AS face_type(type)
FULL JOIN users ON users.face_type=face_type.type
LEFT JOIN houses ON houses.user_id = users.id
GROUP BY face_type.type

答案 2 :(得分:0)

LEFT JOIN开始到ENUMusers的{​​{1}}将允许您为每个枚举值恢复总计。要同时显示houses的面孔类型,可以使用NULL查询。

UNION