考虑到报告月份另一个 table 中的条目,如何根据注册时间对记录进行分组?
How to group records based on registered time considering entries in another table for the reporting month?
我有一个table一个与注册时间关联的帐户,每个id只能有一个条目。
对于 Table A 中存在的所有 ID,Table B 中将有条目,如下所示,状态为
预期转换table
对于 table A 中的每个 ID 如果存在 NO 对应的 ID 条目存在于 table B 中注册时间的月份 - 想要将其归类为该报告月份的新建。同样,如果在 table 中的后续月份中没有相应的条目,B 的 ID 希望将它们分类为 New.
例如:
ID 111 ~ 2020 年 11 月注册 => Table B 没有 ID 111 的条目 => 已转换 table 有 ID 111 的条目11 月份的州为 New。
ID 112 ~ 2020 年 11 月注册 => Table B 在 11 月份有 ID 112 条目 => 已转换 table 没有 ID 112
ID 113 ~ 2020 年 11 月注册 => Table B 从 12 月开始有 ID 113 的条目 => 已转换 table 在 11 月有一个 ID 113 的条目状态为新。
ID 114 ~ 2020 年 11 月注册 => Table B 从 2021 年 2 月开始有 ID 114 的条目 => 已转换 table 在这几个月有一个 ID 114 的条目11 月、12 月、1 月与州新。
如果我没看错,你可以使用 generate_series()
和横向连接:
select a.id, 'new' state, s.dt
from tablea a
cross join lateral (
select generate_series(
date_trunc('month', a.registered_time),
coalesce(
date_trunc('month', min(b.time)) - interval '1 month',
date_trunc('month', a.registered_time)
),
'1 month'
)
from tableb b
where b.id = a.id
) s(dt)
诀窍在于生成 generate_series()
的参数:如果 b
中至少有一个可用条目,我们会从注册月份的月初生成日期系列a
的时间到 b
中最早日期的前一个月;如果 b
中的日期与 a
中的日期相同,则会生成一个空范围,并过滤掉原始行。否则,我们将注册时间作为范围结束(生成由单个日期组成的范围)。
id | state | dt
--: | :---- | :------------------
111 | new | 2020-11-01 00:00:00
113 | new | 2020-11-01 00:00:00
114 | new | 2020-11-01 00:00:00
114 | new | 2020-12-01 00:00:00
114 | new | 2021-01-01 00:00:00
我有一个table一个与注册时间关联的帐户,每个id只能有一个条目。
对于 Table A 中存在的所有 ID,Table B 中将有条目,如下所示,状态为
预期转换table
对于 table A 中的每个 ID 如果存在 NO 对应的 ID 条目存在于 table B 中注册时间的月份 - 想要将其归类为该报告月份的新建。同样,如果在 table 中的后续月份中没有相应的条目,B 的 ID 希望将它们分类为 New.
例如:
ID 111 ~ 2020 年 11 月注册 => Table B 没有 ID 111 的条目 => 已转换 table 有 ID 111 的条目11 月份的州为 New。
ID 112 ~ 2020 年 11 月注册 => Table B 在 11 月份有 ID 112 条目 => 已转换 table 没有 ID 112
ID 113 ~ 2020 年 11 月注册 => Table B 从 12 月开始有 ID 113 的条目 => 已转换 table 在 11 月有一个 ID 113 的条目状态为新。
ID 114 ~ 2020 年 11 月注册 => Table B 从 2021 年 2 月开始有 ID 114 的条目 => 已转换 table 在这几个月有一个 ID 114 的条目11 月、12 月、1 月与州新。
如果我没看错,你可以使用 generate_series()
和横向连接:
select a.id, 'new' state, s.dt
from tablea a
cross join lateral (
select generate_series(
date_trunc('month', a.registered_time),
coalesce(
date_trunc('month', min(b.time)) - interval '1 month',
date_trunc('month', a.registered_time)
),
'1 month'
)
from tableb b
where b.id = a.id
) s(dt)
诀窍在于生成 generate_series()
的参数:如果 b
中至少有一个可用条目,我们会从注册月份的月初生成日期系列a
的时间到 b
中最早日期的前一个月;如果 b
中的日期与 a
中的日期相同,则会生成一个空范围,并过滤掉原始行。否则,我们将注册时间作为范围结束(生成由单个日期组成的范围)。
id | state | dt --: | :---- | :------------------ 111 | new | 2020-11-01 00:00:00 113 | new | 2020-11-01 00:00:00 114 | new | 2020-11-01 00:00:00 114 | new | 2020-12-01 00:00:00 114 | new | 2021-01-01 00:00:00