return 过去 12 个月每个月在 postgres 中发生的所有记录的总和
how return a sum of all the records happened in every month for the last 12 months in postgres
table 看起来像这样
所以我得到了一个看起来像这样的查询
with date_ranges (range_name, range_dates) as
( values ('week_0', tstzrange ((now()::date-interval '6 days'), now(), '[]'))
, ('week_1', tstzrange ((now()::date-interval '13 days'), (now()::date-interval '6 days')))
, ('week_2', tstzrange ((now()::date-interval '20 days'), (now()::date-interval '13 days')))
, ('week_3', tstzrange ((now()::date-interval '27 days'), (now()::date-interval '20 days')))
)
select range_name, range_dates, COALESCE(SUM("transactionTotal"), 0) total_amount
from date_ranges dr
LEFT JOIN "MoneyTransactions" mt on (mt."entryType" = 'sold' AND mt."createdAt" <@ range_dates)
group by range_name, range_dates
order by range_name;
它 return 是过去四个星期每周的总和。现在我正在尝试 return 同样的事情,但不是几周,而是过去 12 个月的总和。
我能够获得上个月的所需日期,例如
SELECT
to_char(now() - series.n * '1 month'::interval, 'month') AS "month",
tstzrange(
date_trunc('month', now()) - series.n * '1 month'::interval,
date_trunc('month', now()) - (series.n - 1) * '1 month'::interval,
'[]'
) AS range_dates
FROM (
SELECT generate_series(0, 11) AS n
) AS series
我试过了,显然它不起作用
with date_ranges (range_name, range_dates) as
( values (
to_char(now() - series.n * '1 month'::interval, 'month') as "month",
tstzrange(
date_trunc('month', now()) - series.n * '1 month'::interval,
date_trunc('month', now()) - (series.n - 1) * '1 month'::interval,
'[]'
))
)
select range_name, range_dates(0, 11), COALESCE(SUM("transactionTotal"), 0) total_amount
from date_ranges dr
LEFT JOIN "MoneyTransactions" mt on (mt."entryType" = 'sold' AND mt."createdAt" <@ range_dates)
group by range_name, range_dates
order by range_name;
但是我对 SQL 的有限了解使我无法将所有这些放在一个查询中以获得所需的输出,看起来像这样
[
{
"range_name": "september",
"range_dates": [
{
"value": "2020-09-01T00:00:00.000Z",
"inclusive": true
},
{
"value": "2020-10-01T00:00:00.000Z",
"inclusive": false
}
],
"total_amount": "253050"
},
{
"range_name": "august",
"range_dates": [
{
"value": "2020-08-01T00:00:00.000Z",
"inclusive": true
},
{
"value": "2020-09-01T00:00:00.000Z",
"inclusive": false
}
],
"total_amount": "55200"
},
...
]
有好心人帮忙吗
这是获得 12 个月范围的更简洁的方法。根据日期在 money_transactions
中的样子,您可以轻松地使用它们与 create_date
列进行比较。
to_char
returns 是不同格式的 varchar,在我的示例中,我使用 MM/YYYY
,它将 return 10/2019
用于 2019 年 10 月。您必须确保生成的系列日期和 MoneyTransactions
列 createdAt
日期格式匹配。不过,您可以随意调整它。
with date_range as
(
select
to_char(months, 'MM/YYYY') as "month" -- returns month/year 10/19
from
generate_series( date_trunc('month', current_date - interval '11 months'), date_trunc('month', current_date), '1 month':: interval) as months
)
select
dr."month",
COALESCE(SUM("transactionTotal"), 0) total_amount
from
date_range dr
left join
"MoneyTransactions" mt
on mt."entryType" = 'sold'
and to_char(mt."createdAt", 'MM/YYYY') = dr."month"
group by
dr."month";
另外,SQL 命名约定建议在您的标识符(表、列等)中使用 snake_case
和所有小写字母,因此 money_transactions
而不是 MoneyTransactions
.
table 看起来像这样
所以我得到了一个看起来像这样的查询
with date_ranges (range_name, range_dates) as
( values ('week_0', tstzrange ((now()::date-interval '6 days'), now(), '[]'))
, ('week_1', tstzrange ((now()::date-interval '13 days'), (now()::date-interval '6 days')))
, ('week_2', tstzrange ((now()::date-interval '20 days'), (now()::date-interval '13 days')))
, ('week_3', tstzrange ((now()::date-interval '27 days'), (now()::date-interval '20 days')))
)
select range_name, range_dates, COALESCE(SUM("transactionTotal"), 0) total_amount
from date_ranges dr
LEFT JOIN "MoneyTransactions" mt on (mt."entryType" = 'sold' AND mt."createdAt" <@ range_dates)
group by range_name, range_dates
order by range_name;
它 return 是过去四个星期每周的总和。现在我正在尝试 return 同样的事情,但不是几周,而是过去 12 个月的总和。
我能够获得上个月的所需日期,例如
SELECT
to_char(now() - series.n * '1 month'::interval, 'month') AS "month",
tstzrange(
date_trunc('month', now()) - series.n * '1 month'::interval,
date_trunc('month', now()) - (series.n - 1) * '1 month'::interval,
'[]'
) AS range_dates
FROM (
SELECT generate_series(0, 11) AS n
) AS series
我试过了,显然它不起作用
with date_ranges (range_name, range_dates) as
( values (
to_char(now() - series.n * '1 month'::interval, 'month') as "month",
tstzrange(
date_trunc('month', now()) - series.n * '1 month'::interval,
date_trunc('month', now()) - (series.n - 1) * '1 month'::interval,
'[]'
))
)
select range_name, range_dates(0, 11), COALESCE(SUM("transactionTotal"), 0) total_amount
from date_ranges dr
LEFT JOIN "MoneyTransactions" mt on (mt."entryType" = 'sold' AND mt."createdAt" <@ range_dates)
group by range_name, range_dates
order by range_name;
但是我对 SQL 的有限了解使我无法将所有这些放在一个查询中以获得所需的输出,看起来像这样
[
{
"range_name": "september",
"range_dates": [
{
"value": "2020-09-01T00:00:00.000Z",
"inclusive": true
},
{
"value": "2020-10-01T00:00:00.000Z",
"inclusive": false
}
],
"total_amount": "253050"
},
{
"range_name": "august",
"range_dates": [
{
"value": "2020-08-01T00:00:00.000Z",
"inclusive": true
},
{
"value": "2020-09-01T00:00:00.000Z",
"inclusive": false
}
],
"total_amount": "55200"
},
...
]
有好心人帮忙吗
这是获得 12 个月范围的更简洁的方法。根据日期在 money_transactions
中的样子,您可以轻松地使用它们与 create_date
列进行比较。
to_char
returns 是不同格式的 varchar,在我的示例中,我使用 MM/YYYY
,它将 return 10/2019
用于 2019 年 10 月。您必须确保生成的系列日期和 MoneyTransactions
列 createdAt
日期格式匹配。不过,您可以随意调整它。
with date_range as
(
select
to_char(months, 'MM/YYYY') as "month" -- returns month/year 10/19
from
generate_series( date_trunc('month', current_date - interval '11 months'), date_trunc('month', current_date), '1 month':: interval) as months
)
select
dr."month",
COALESCE(SUM("transactionTotal"), 0) total_amount
from
date_range dr
left join
"MoneyTransactions" mt
on mt."entryType" = 'sold'
and to_char(mt."createdAt", 'MM/YYYY') = dr."month"
group by
dr."month";
另外,SQL 命名约定建议在您的标识符(表、列等)中使用 snake_case
和所有小写字母,因此 money_transactions
而不是 MoneyTransactions
.