如何根据分区 - sql 分配支出金额?
How to distribute spend amount based on partition - sql?
我有以下 table:
站点
次级
part_number
站点 A
AA
123
站点 A
AB
1234
站点 A
AB
12345
站点 B
AA
123
站点 B
AB
1234
站点 B
AB
12345
站点 C
AA
123
站点 C
AB
1234
站点 C
AB
12345
基于以上:
有 3 个不同的站点、2 个不同的子层和 3 个不同的部分
我的消费总额为 964520.15625
这笔款项需要分配如下:
网站
次级
part_number
过去的支出
站点 A
AA
123
160753.359
站点 A
AB
1234
80376.6797
站点 A
AB
12345
80376.6797
站点 B
AA
123
160753.359
站点 B
AB
1234
80376.6797
站点 B
AB
12345
80376.6797
站点 C
AA
123
160753.359
站点 C
AB
1234
80376.6797
站点 C
AB
12345
80376.6797
对过去的支出列求和后,总计为 964520.15625
分解:
网站
次级
part_number
过去的支出
公式
站点 A
AA
123
160753.359
964520.15625 / 3 / 2
站点 A
AB
1234
80376.6797
964520.15625 / 3 / 2 / 2
站点 A
AB
12345
80376.6797
964520.15625 / 3 / 2 / 2
/ 3 / 2 / 2:
3 表示站点(站点 A、B 和 C)的不同计数
2 表示子层(AA、AB)的不同计数
2(最后一个)代表站点 A --> AB 有 2 个部件号
我需要帮助构建 SQL 为此。
我试过:
CASE
WHEN (
site_cnt != 0 AND subtier_cnt != 0 AND part_num_cnt
!= 0 AND past_spend IS NOT NULL
) THEN ((past_spend/ site_cnt) / subtier__cnt)
/ part_num_cnt
WHEN (
site_cnt != 0 AND subtier_cnt = 0 AND part_num_cnt
= 0 AND past_spend IS NOT NULL
) THEN (past_spend / site_cnt)
ELSE past_spend
END AS past_spend
所有行的结果都是 53584.4531,这是不正确的
我还尝试使用 window 函数划分过去的支出金额:
past_spend / count() over (partition by site, subtier, part_number)
感谢任何帮助!
如果您的数据库支持 count(distinct)
作为 window 函数:
select t.*,
(964520.15625 /
(count(distinct site) over () *
count(distinct subtier) over (site) *
count(distinct partnumber) over (partition by site, subtier)
)
)
from t;
即使在不支持 count(distinct)
作为 window 函数的数据库中,也有一些方法可以解决这个问题(假设逻辑是正确的)。
我有以下 table:
站点 | 次级 | part_number |
---|---|---|
站点 A | AA | 123 |
站点 A | AB | 1234 |
站点 A | AB | 12345 |
站点 B | AA | 123 |
站点 B | AB | 1234 |
站点 B | AB | 12345 |
站点 C | AA | 123 |
站点 C | AB | 1234 |
站点 C | AB | 12345 |
基于以上:
有 3 个不同的站点、2 个不同的子层和 3 个不同的部分
我的消费总额为 964520.15625
这笔款项需要分配如下:
网站 | 次级 | part_number | 过去的支出 |
---|---|---|---|
站点 A | AA | 123 | 160753.359 |
站点 A | AB | 1234 | 80376.6797 |
站点 A | AB | 12345 | 80376.6797 |
站点 B | AA | 123 | 160753.359 |
站点 B | AB | 1234 | 80376.6797 |
站点 B | AB | 12345 | 80376.6797 |
站点 C | AA | 123 | 160753.359 |
站点 C | AB | 1234 | 80376.6797 |
站点 C | AB | 12345 | 80376.6797 |
对过去的支出列求和后,总计为 964520.15625
分解:
网站 | 次级 | part_number | 过去的支出 | 公式 |
---|---|---|---|---|
站点 A | AA | 123 | 160753.359 | 964520.15625 / 3 / 2 |
站点 A | AB | 1234 | 80376.6797 | 964520.15625 / 3 / 2 / 2 |
站点 A | AB | 12345 | 80376.6797 | 964520.15625 / 3 / 2 / 2 |
/ 3 / 2 / 2:
3 表示站点(站点 A、B 和 C)的不同计数 2 表示子层(AA、AB)的不同计数 2(最后一个)代表站点 A --> AB 有 2 个部件号
我需要帮助构建 SQL 为此。
我试过:
CASE
WHEN (
site_cnt != 0 AND subtier_cnt != 0 AND part_num_cnt
!= 0 AND past_spend IS NOT NULL
) THEN ((past_spend/ site_cnt) / subtier__cnt)
/ part_num_cnt
WHEN (
site_cnt != 0 AND subtier_cnt = 0 AND part_num_cnt
= 0 AND past_spend IS NOT NULL
) THEN (past_spend / site_cnt)
ELSE past_spend
END AS past_spend
所有行的结果都是 53584.4531,这是不正确的
我还尝试使用 window 函数划分过去的支出金额:
past_spend / count() over (partition by site, subtier, part_number)
感谢任何帮助!
如果您的数据库支持 count(distinct)
作为 window 函数:
select t.*,
(964520.15625 /
(count(distinct site) over () *
count(distinct subtier) over (site) *
count(distinct partnumber) over (partition by site, subtier)
)
)
from t;
即使在不支持 count(distinct)
作为 window 函数的数据库中,也有一些方法可以解决这个问题(假设逻辑是正确的)。