使用某个日期范围内的数据创建多个 SUM 列,其中一列合并了第三个连接 table 中的数据
Create multiple SUM columns with data from a date range, where one column combines data from a joined third table
我正在创建一个查询,该查询按 'entity' 列分组并输出 4 个新列。
- 这些新列根据日期范围从每个 'entity' 的 'amount' 列中求和或减去金额值。
- 我也在尝试加入第 3 个 table (previous_year_table) 并包含其中的数据。
关于如何使以下查询成为可能的任何指导?或有关更高效查询的指导?
我正在构建的实际查询在第二个代码块中。
SELECT
ent.entity,
SUM(data.amount) curr_month /* when data.ds between 1st of current month AND current date)*/
SUM(data.amount) prev_month /* when data.ds between 1st of previous month AND current date)*/
(SUBTRACT prev_month sum from curr_month sum) movement,
(
SUM(prev_data.amount) /* when prev_data.ds between 1st day of Previous year AND current date)*/
+ SUM(data.amount) /* when data.ds between 1st day of Current year AND current date)*/
) previous_year
FROM entity_table ent
JOIN current_year_table data
ON data.unit = ent.unit
JOIN previous_year_table prev_data
ON prev_data.unit = ent.unit
GROUP BY
entity;
我当前执行的上述查询
这没有 'previous_year_table' 加入,到目前为止似乎可以工作,但感觉很老套。
我也使用 prestodb 语法,例如DATE_TRUNC
、current_date
等
SELECT
ent.entity,
SUM(
CASE
WHEN data.ds BETWEEN CAST(DATE_TRUNC('month', current_date) AS VARCHAR)
AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
) curr_month,
SUM(
CASE
WHEN data.ds BETWEEN CAST(
(DATE_TRUNC('month', current_date) - INTERVAL '1' MONTH) AS VARCHAR
) AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
) prev_month,
(
SUM(
CASE
WHEN data.ds BETWEEN CAST(DATE_TRUNC('month', current_date) AS VARCHAR)
AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
) - SUM(
CASE
WHEN data.ds BETWEEN CAST(
(DATE_TRUNC('month', current_date) - INTERVAL '1' MONTH) AS VARCHAR
) AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
)
) movement
FROM entity_table ent
JOIN current_year_table data
ON data.operating_unit = ent.operating_unit
GROUP BY
entity;
所需的查询输出
entity
current_month
previous_month
movement(curr - prev)
previous_year
entity_1
20
40
-20
70
entity_2
10
50
-40
90
查询输入表
Entity_Table 单位列与####_Year_Table 单位列之间的'many' 关系
Entity_Table
entity
unit (join col)
entity_1
1
entity_2
2
当前_Year_Table
unit (join col)
amount
ds (datestamp string, curr year)
1
20
2022-05-21
1
20
2022-04-19
2
10
2022-05-20
2
40
2022-04-26
上一个_Year_Table
unit (join col)
amount
ds (datestamp string, prev year)
1
20
2021-08-29
2
30
2021-03-18
2
10
2021-01-21
1
10
2021-02-13
你的 movement
公式很奇怪,原因是这两个:
curr_month /* when data.ds between 1st of current month AND current date)/
prev_month / when data.ds between 1st of previous month AND current date)*/
movement
将始终只是上个月(一个月的第一天和最后一天之间)的一些负号。
另外,根据数据,似乎 previous_year
您实际上需要当前年份和前几年的总和。
除此之外,您的方法还不错,我建议使用 if
进行小的调整,子选择并使用数据函数以使其更具可读性:
--sample data
WITH entity_table (entity, operating_unit) AS (
VALUES ('entity_1', 1),
('entity_2', 2)
),
current_year_table (operating_unit, amount_usd, ds) AS (
VALUES
(1, 20, '2022-05-21'),
(1, 20, '2022-04-19'),
(2, 10, '2022-05-20'),
(2, 40, '2022-04-26')
),
previous_year_table (operating_unit, amount_usd, ds) AS (
VALUES
(1, 20, '2021-08-29'),
(2, 30, '2021-03-18'),
(2, 10, '2021-01-21'),
(1, 10, '2021-02-13')
)
查询:
-- query
select entity,
curr_month,
prev_month,
curr_month - prev_month as movement,
total_current_year + previous_year as previous_year
from (
select ent.entity,
ent.operating_unit,
sum(
if(
DATE_TRUNC('month', date(data.ds)) = DATE_TRUNC('month', now()),
amount_usd,
0
)
) curr_month,
sum(
if(
// use = instead of >= if you want actual diff between current and previous month
DATE_TRUNC('month', date(data.ds)) >= DATE_TRUNC('month', now()) - interval '1' month,
amount_usd,
0
)
) prev_month,
sum(amount_usd) total_current_year
FROM entity_table ent
JOIN current_year_table data ON data.operating_unit = ent.operating_unit
GROUP BY entity,
ent.operating_unit
) as current_year_data
join (
select operating_unit,
sum(amount_usd) as previous_year
from previous_year_table
group by operating_unit
) previous_year_data on current_year_data.operating_unit = previous_year_data.operating_unit
输出:
entity
curr_month
prev_month
movement
previous_year
entity_1
20
40
-20
70
entity_2
10
50
-40
90
我正在创建一个查询,该查询按 'entity' 列分组并输出 4 个新列。
- 这些新列根据日期范围从每个 'entity' 的 'amount' 列中求和或减去金额值。
- 我也在尝试加入第 3 个 table (previous_year_table) 并包含其中的数据。
关于如何使以下查询成为可能的任何指导?或有关更高效查询的指导?
我正在构建的实际查询在第二个代码块中。
SELECT
ent.entity,
SUM(data.amount) curr_month /* when data.ds between 1st of current month AND current date)*/
SUM(data.amount) prev_month /* when data.ds between 1st of previous month AND current date)*/
(SUBTRACT prev_month sum from curr_month sum) movement,
(
SUM(prev_data.amount) /* when prev_data.ds between 1st day of Previous year AND current date)*/
+ SUM(data.amount) /* when data.ds between 1st day of Current year AND current date)*/
) previous_year
FROM entity_table ent
JOIN current_year_table data
ON data.unit = ent.unit
JOIN previous_year_table prev_data
ON prev_data.unit = ent.unit
GROUP BY
entity;
我当前执行的上述查询
这没有 'previous_year_table' 加入,到目前为止似乎可以工作,但感觉很老套。
我也使用 prestodb 语法,例如DATE_TRUNC
、current_date
等
SELECT
ent.entity,
SUM(
CASE
WHEN data.ds BETWEEN CAST(DATE_TRUNC('month', current_date) AS VARCHAR)
AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
) curr_month,
SUM(
CASE
WHEN data.ds BETWEEN CAST(
(DATE_TRUNC('month', current_date) - INTERVAL '1' MONTH) AS VARCHAR
) AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
) prev_month,
(
SUM(
CASE
WHEN data.ds BETWEEN CAST(DATE_TRUNC('month', current_date) AS VARCHAR)
AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
) - SUM(
CASE
WHEN data.ds BETWEEN CAST(
(DATE_TRUNC('month', current_date) - INTERVAL '1' MONTH) AS VARCHAR
) AND CAST(current_date AS VARCHAR) THEN data.amount_usd
ELSE 0
END
)
) movement
FROM entity_table ent
JOIN current_year_table data
ON data.operating_unit = ent.operating_unit
GROUP BY
entity;
所需的查询输出
entity | current_month | previous_month | movement(curr - prev) | previous_year |
---|---|---|---|---|
entity_1 | 20 | 40 | -20 | 70 |
entity_2 | 10 | 50 | -40 | 90 |
查询输入表
Entity_Table 单位列与####_Year_Table 单位列之间的'many' 关系
Entity_Table
entity | unit (join col) |
---|---|
entity_1 | 1 |
entity_2 | 2 |
当前_Year_Table
unit (join col) | amount | ds (datestamp string, curr year) |
---|---|---|
1 | 20 | 2022-05-21 |
1 | 20 | 2022-04-19 |
2 | 10 | 2022-05-20 |
2 | 40 | 2022-04-26 |
上一个_Year_Table
unit (join col) | amount | ds (datestamp string, prev year) |
---|---|---|
1 | 20 | 2021-08-29 |
2 | 30 | 2021-03-18 |
2 | 10 | 2021-01-21 |
1 | 10 | 2021-02-13 |
你的 movement
公式很奇怪,原因是这两个:
curr_month /* when data.ds between 1st of current month AND current date)/
prev_month / when data.ds between 1st of previous month AND current date)*/
movement
将始终只是上个月(一个月的第一天和最后一天之间)的一些负号。
另外,根据数据,似乎 previous_year
您实际上需要当前年份和前几年的总和。
除此之外,您的方法还不错,我建议使用 if
进行小的调整,子选择并使用数据函数以使其更具可读性:
--sample data
WITH entity_table (entity, operating_unit) AS (
VALUES ('entity_1', 1),
('entity_2', 2)
),
current_year_table (operating_unit, amount_usd, ds) AS (
VALUES
(1, 20, '2022-05-21'),
(1, 20, '2022-04-19'),
(2, 10, '2022-05-20'),
(2, 40, '2022-04-26')
),
previous_year_table (operating_unit, amount_usd, ds) AS (
VALUES
(1, 20, '2021-08-29'),
(2, 30, '2021-03-18'),
(2, 10, '2021-01-21'),
(1, 10, '2021-02-13')
)
查询:
-- query
select entity,
curr_month,
prev_month,
curr_month - prev_month as movement,
total_current_year + previous_year as previous_year
from (
select ent.entity,
ent.operating_unit,
sum(
if(
DATE_TRUNC('month', date(data.ds)) = DATE_TRUNC('month', now()),
amount_usd,
0
)
) curr_month,
sum(
if(
// use = instead of >= if you want actual diff between current and previous month
DATE_TRUNC('month', date(data.ds)) >= DATE_TRUNC('month', now()) - interval '1' month,
amount_usd,
0
)
) prev_month,
sum(amount_usd) total_current_year
FROM entity_table ent
JOIN current_year_table data ON data.operating_unit = ent.operating_unit
GROUP BY entity,
ent.operating_unit
) as current_year_data
join (
select operating_unit,
sum(amount_usd) as previous_year
from previous_year_table
group by operating_unit
) previous_year_data on current_year_data.operating_unit = previous_year_data.operating_unit
输出:
entity | curr_month | prev_month | movement | previous_year |
---|---|---|---|---|
entity_1 | 20 | 40 | -20 | 70 |
entity_2 | 10 | 50 | -40 | 90 |