从创建日期开始按年龄范围分组的 SQL 查询

bar*_*oma 6 sql postgresql

我想通过 sql 查询获取统计信息。我的表是这样的:

ID MATERIAL CREATEDATE DEPARTMENT
1  M1       10.10.1980 D1
2  M2       11.02.1970 D2
2  M3       18.04.1971 D3
.....................
.....................
.....................
Run Code Online (Sandbox Code Playgroud)

我怎样才能获得这样的数据计数范围

DEPARTMENT AGE<10  10<AGE<20 20<AGE
D1         24       123      324
D2         24       123      324
Run Code Online (Sandbox Code Playgroud)

fth*_*lla 5

假设 CREATEDATE 是一个日期列,在 PostgreSQL 中你可以使用AGE函数:

select DEPARTMENT, age(CREATEDATE) as AGE
from Materials
Run Code Online (Sandbox Code Playgroud)

使用 date_part 您可以获得以年为单位的年龄。要以您想要的格式显示数据,您可以使用这个 GROUP BY 查询:

select
  DEPARTMENT,
  sum(case when date_part('year', age(CREATEDATE))<10 then 1 end) as "age<10",
  sum(case when date_part('year', age(CREATEDATE))>=10 and date_part('year', age(CREATEDATE))<20 then 1 end) as "10<age<20",
  sum(case when date_part('year', age(CREATEDATE))>=20 then 1 end) as "20<age"
from
  Materials
group by
  DEPARTMENT
Run Code Online (Sandbox Code Playgroud)

可以简化为:

with mat_age as (
  select DEPARTMENT, date_part('year', age(CREATEDATE)) as mage
  from Materials
)
select
  DEPARTMENT,
  sum(case when mage<10 then 1 end) as "age<10",
  sum(case when mage>=10 and mage<20 then 1 end) as "10<age<20",
  sum(case when mage>=20 then 1 end) as "20<age"
from
  mat_age
group by
  DEPARTMENT;
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 PostgreSQL 9.4,则可以使用 FILTER:

with mat_age as (
  select DEPARTMENT, date_part('year', age(CREATEDATE)) as mage
  from Materials
)
select
  DEPARTMENT,
  count(*) filter (where mage<10) as "age<10",
  count(*) filter (where mage>=10 and mage<20) as "10<age<20",
  count(*) filter (where mage>=20) as "20<age"
from
  mat_age
group by
  DEPARTMENT;
Run Code Online (Sandbox Code Playgroud)

  • @TimBiegeleisen 我正在使用您未使用的 AGE 函数,我使用的是您未使用的 CTE,我使用的是 PostgreSQL 9.4 新的 FILTER ......我也跳过了` ELSE 0` 部分,因为它不是必需的,并且您使用的是 ' 而不是 " ... 它在很大程度上不是相同的 (2认同)