计算未明确列出的年份

问题描述 投票:0回答:1

这是一个表格:

CREATE TABLE table_b (
  name VARCHAR(255),
  date_2 DATE,
  date_3 DATE,
  var CHAR(1)
);


INSERT INTO table_b (name, date_2, date_3, var) VALUES
('john', '2001-01-01', '2015-01-01', 'b'),
('sara', '2000-01-01', '2015-01-01', 'c'),
('sara', '2015-01-02', '2022-01-01', 'a'),
('tim', '2020-01-01', '2021-01-01', 'a'),
('john', '1998-01-01', '1999-01-01', 'd');

#table_b



name     date_2     date_3 var
 john 2001-01-01 2015-01-01   b
 sara 2000-01-01 2015-01-01   c
 sara 2015-01-02 2022-01-01   a
  tim 2020-01-01 2021-01-01   a
 john 1998-01-01 1999-01-01   d

在总体最小年份和最大年份之间,我想知道:每年,有多少人有此表中的记录?

这是我想到的方法:

with years as (
select 1998 as year
union all 
select 1999
union all
##etc etc)

counts as 
(select y.year
count(distinct t.name) as count
from table_b t
join years y
on t.date_2 <= date(y.year || '-12-31') and t.date_3  >= date(y.year || '-01-01')
group by y.year)
select * from counts;

有没有一种更简单的方法可以做到这一点,而无需手动列出所有年份?

db2
1个回答
0
投票

您可以使用递归 CTE 从现有日期字段构建年份列表。您可以在 CTE 内获取最小日期(来自

date_2
)和
UNION ALL
,并具有最大年份的停止条件(来自
date_3
)。

此示例假设

date_2
始终小于相应的
date_3

WITH YEARS_LIST (YR, YR_STOP) AS (
    SELECT
        YEAR(MIN(DATE_2)) AS YR,
        YEAR(MAX(DATE_3)) AS YR_STOP
    FROM TABLE_B

    UNION ALL

    -- Generate a row for each year until we get to the max year
    SELECT
        YR + 1 AS YR,
        YR_STOP
    FROM YEARS_LIST
    WHERE YR < YR_STOP
),

COUNTS AS (
    SELECT
        Y.YR,
        COUNT(DISTINCT T.NAME) AS REC_COUNT
    FROM TABLE_B AS T
    INNER JOIN YEARS_LIST AS Y
        ON
            T.DATE_2 <= DATE(Y.YR || '-12-31')
            AND T.DATE_3 >= DATE(Y.YR || '-01-01')
    GROUP BY Y.YR
)

SELECT *
FROM COUNTS;

注意:我修改了示例中的一些列名称,以避免使用某些关键字(例如 YEAR、COUNT)。

CTE 的第一次迭代将生成如下行:

YR_STOP
1998 2022

CTE 中的第二个 select 语句将循环,生成一行,其中

YR
加 1,直到
YR
等于或大于
YR_STOP

生成的 CTE 将类似于以下内容:

YR_STOP
1998 2022
1999 2022
2000 2022
... ...
2021 2022
2022 2022
© www.soinside.com 2019 - 2024. All rights reserved.