使用每列的选择性聚合从两列创建 SQL 值
Posted
技术标签:
【中文标题】使用每列的选择性聚合从两列创建 SQL 值【英文标题】:Creating SQL values from two columns using the selective aggregate of each column 【发布时间】:2021-11-01 22:40:18 【问题描述】:我有以下四个表: region_reference、community_grants、HealthWorkers 和 currency_exchange
以及以下有效的 SQL 查询:
SELECT HealthWorkers.worker_id
, community_grants.percentage_price_adjustment
, community_grants.payment_status
, community_grants.chosen
, (region_reference.base_price * currency_exchange.euro_value) AS price
FROM currency_exchange
INNER JOIN (
region_reference INNER JOIN (
HealthWorkers INNER JOIN community_grants
ON HealthWorkers.worker_id = community_grants.worker_id
) ON (
region_reference.community_id = community_grants.community_id
) AND (region_reference.region_id = community_grants.region_id)
)
ON currency_exchange.currency = HealthWorkers.preferred_currency
WHERE (
HealthWorkers.worker_id="malawi_01"
AND community_grants.chosen=True
);
它给了我以下结果集:
但是,我的任务是创建一个仅包含 4 个值的实体。
type OverallPriceSummary struct
Worker_id string `json:"worker_id"`
Total_paid decimal.Decimal `json:"total_paid"`
Total_pledged decimal.Decimal `json:"total_pledged"`
Total_outstanding decimal.Decimal `json:"total_outstanding"`
Total_paid 是指定 worker_id 的值的总和,其中 payment_status = “1”(所有记录的组合)
Total_outstanding 是 payment_status 为“0”且选择为 true 的值的总和(所有记录的组合)
Total_pledged 是 Total_paid 和 Total_outstanding 的总和(所有记录也合并)
我目前通过在我的代码中手动聚合这些值来获取这些值,因为 postgresql 会遍历结果集,但我相信有一种方法可以避免这个临时 SQL 查询并从单个 SQL 查询中获得我需要的东西。 我怀疑它涉及使用 SUM AS 和内部查询,但我不知道如何将它们组合在一起。任何帮助或指导将不胜感激。
编辑: 我在下面提供了一些示例数据:
region_reference
region_id | region_name | base_price | community_id |
---|---|---|---|
1 | Lilongwe | 100 | 19 |
2 | Mzuzu | 50 | 19 |
卫生工作者
worker_id | worker_name | preferred_currency | billing_address | charity_logo |
---|---|---|---|---|
malawi_01 | Raphael Salanga | EUR | Nkhunga Health Centre in Nkhotakota District | 12345 |
community_grants
region_id | campaign_id | worker_id | percentage_price_adjustment | community_id | payment_status | chosen | paid_price |
---|---|---|---|---|---|---|---|
1 | 1 | malawi_01 | 10 | 19 | 0 | Yes | 0 |
2 | 1 | malawi_01 | 0 | 19 | 1 | Yes | 20 |
3 | 1 | malawi_01 | 1 | 19 | 0 | Yes | 0 |
1 | 1 | malawi_01 | 0 | 23 | 0 | Yes | 30 |
currency_exchange
currency | currency_symbol | euro_value |
---|---|---|
EUR | € | 1 |
USD | $ | 0.84 |
【问题讨论】:
请在您的问题中提供一些示例数据,以及您希望使用该数据实现的结果 您的图像和 SQL 表示 MS Access,但您提到并标记了 Postgres。您是否在 Access GUI 中使用 Postgres 链接表?还是您需要直通查询?这很重要,因为 SQL 方言在 Access 和 Postgres 之间会有所不同。 @Parfait 我继承了一个 MSAccess 数据库,所以我用它来将查询放在一起,查询也适用于 Postgresql。我很高兴方言纯粹是 Postgresql 特有的。我想知道如何优化 MS Access 生成的内容也会很有用。 什么是值的总和?总价表示为:region_reference.base_price * currency_exchange.euro_value) AS price
?
它稍微复杂一些,(region_reference.base_price * currency_exchange.euro_value)+(currency_exchange.euro_value*region_reference.base_price * (community_pricing.percentage_price_adjustment/100)) AS 价格,但同样的想法也适用
【参考方案1】:
考虑使用 Postgres 的 FILTER
子句进行条件聚合,在该子句中将数据透视到计算的条件列。
以下假设 值的总和 是计算价格的总和,表示为:region_reference.base_price * currency_exchange.euro_value
。根据需要进行调整。
SELECT h.worker_id
, SUM(r.base_price * ce.euro_value) FILTER(WHERE
cg.payment_status = 1
) AS total_paid
, SUM(r.base_price * ce.euro_value) FILTER(WHERE
cg.payment_status = 0 AND
cg.chosen=True
) AS total_outstanding
, SUM(r.base_price * ce.euro_value) FILTER(WHERE
(cg.payment_status = 1) OR
(cg.payment_status = 0 AND cg.chosen=True)
) AS total_pledged
FROM community_grants cg
INNER JOIN region_reference r
ON r.community_id = cg.community_id
AND r.region_id = cg.region_id
INNER JOIN HealthWorkers h
ON h.worker_id = cg.worker_id
AND h.worker_id = 'malawi_01'
INNER JOIN currency_exchange ce
ON ce.currency = h.preferred_currency
GROUP BY h.worker_id
【讨论】:
我需要在每次使用 Filter 的地方添加 FILTER( 但效果很好 哎呀!谢谢你的忽视。相应地进行了编辑。或者,使用CASE
(可移植到其他RDBMS)但不幸的是不能访问yet!【参考方案2】:
尝试类似:
SELECT
worker_id
,sum(case when payment_status = “1”
then paid_price else 0 end) as Total_paid
,sum(case when payment_status = “0” and chosen = true
then paid_price else 0 end) as Total_outstanding
,sum(case when (payment_status = “1”)
or (payment_status = “0” and chosen = true)
then paid_price else 0 end) as Total_pledged
from community_grants
group by worker_id
【讨论】:
刚刚意识到这会跳过其他表的链接以上是关于使用每列的选择性聚合从两列创建 SQL 值的主要内容,如果未能解决你的问题,请参考以下文章