【问题标题】:SUM of a field in INNER JOIN in PostgreSQLPostgreSQL 中 INNER JOIN 中字段的总和
【发布时间】:2020-04-03 16:18:48
【问题描述】:

我有一个这样的查询:

SELECT      pt.id, 
            pt.plan_name,
            pt.product_disc_amt,
            pt.product_disc_perc, 
            SUM(ac.premium_amount) AS premium,
            ac.id AS ac_id 
FROM        product pt 
INNER JOIN  age_classification ac 
ON          ac.p_id = pt.id 
WHERE       pt.medical_coverage_for = 'dependents_only'
OR          (ac.relationship = 'child' AND ac.age_from::int <= 3 AND ac.age_to::  int >= 3  
AND         ac.gender = 'female' AND ac.marital_status = 'single') 
OR          (ac.relationship = 'child' AND ac.age_from::int <= 4 AND ac.age_to::  int >= 4  
AND         ac.gender = 'male' AND ac.marital_status = 'single' ) 
OR          (ac.relationship = 'child' AND ac.age_from::int <= 2 
AND         ac.age_to::  int >= 2  AND ac.gender = 'female' AND ac.marital_status = 'single')    
GROUP BY    pt.id, 
            ac.premium_amount,
            ac.id

在此查询中,age_classification 是与产品的 One2Many 关系。通过p_id关联。

我得到这样的 o/p:

id      plan_name   product_disc_amt    product_disc_perc       premium         ac_id
295     A           0                   0                       110             75
1543    B           0                   0                       90              69
1543    B           0                   0                       95              70
1543    B           0                   0                       132             71

我的预期输出是:

id      plan_name   product_disc_amt    product_disc_perc       premium         ac_id
295     A           0                   0                       110             75
1543    B           0                   0                       317             69 <------ Sample Value

ac_id 不必是 69。我只是在那里写了一个 id,它在我得到的输出中。 ac_id 中没有必要有值。我只是给出了列来显示关系。因为它是在SELECT 语句中给出的,所以我不知道预期输出中会出现什么值。所以我给了一个值。

那是我想得到 id 1543 上的 premium_amount 的总和。该行正在重复。由于我是 SQL 新手,因此我没有得到解决方法。提前致谢。

【问题讨论】:

  • 为什么输出行的ac_id 是69?如果没有正确分组,您将如何在返回的三行之间进行选择?
  • @Martin,抱歉 ac_id 不必是 69。我刚刚在我得到的 o/p 中写了一个 id。 ac_id 中没有必要有值。我只是给出了列来显示关系。因为它是在SELECT 语句中给出的,所以我不知道预期的o/p 中会出现什么值。所以我给了一个值。
  • 您自己承认“ac_id 中没有必要有值”。然后不要在那里 - 从选择和组列表中删除它和 .正因为如此,你才能得到你想要的结果,而不是你想要的。

标签: sql postgresql join group-by


【解决方案1】:

您还应该将plan_name 转换为GROUP BYac_id 列还可以防止合并行。这里聚合可能会有所帮助:

SELECT      pt.id, 
            pt.plan_name,
            pt.product_disc_amt,
            pt.product_disc_perc, 
            SUM(ac.premium_amount) AS premium,
            MAX(ac.id) AS ac_id
FROM        product pt 
INNER JOIN  age_classification ac 
ON          ac.p_id = pt.id 
WHERE       pt.medical_coverage_for = 'dependents_only'
OR          (ac.relationship = 'child' AND ac.age_from::int <= 3 AND ac.age_to::  int >= 3  
AND         ac.gender = 'female' AND ac.marital_status = 'single') 
OR          (ac.relationship = 'child' AND ac.age_from::int <= 4 AND ac.age_to::  int >= 4  
AND         ac.gender = 'male' AND ac.marital_status = 'single' ) 
OR          (ac.relationship = 'child' AND ac.age_from::int <= 2 
AND         ac.age_to::  int >= 2  AND ac.gender = 'female' AND ac.marital_status = 'single')    
GROUP BY    pt.id, 
            pt.plan_name,
            ac.premium_amount,
            pt.product_disc_perc

【讨论】:

  • 看起来“ac_id”不是必需的。这是正确的,但请记住,该字段结果在解释方面没有任何意义。
  • 我在 SELECT 中添加了 MAX(ac.id) AS ac_id,在 GROUP 中添加了 pt.plan_name,但它仍然显示 3 行。
  • 啊,我错过了 GROUP BY 中的 pt.product_disc_perc。
【解决方案2】:

通过查看您当前的结果,我了解到您希望记录按 idplan_name 分组。

ac_id 应该放在一个聚合函数中,可能是min()

此外,您想从 group by 子句中删除列 ac.premium,因为您在其上使用了聚合函数。

最后:我假设列 product_disc_amtproduct_disc_perc 的功能依赖于属于 group by 子句的其他列(否则,您还需要将它们添加到 group by 子句中)。

考虑:

SELECT      pt.id, 
            pt.plan_name,
            pt.product_disc_amt,
            pt.product_disc_perc, 
            SUM(ac.premium_amount) AS premium,
            MIN(ac.id) AS ac_id 
FROM        product pt 
INNER JOIN  age_classification ac 
ON          ac.p_id = pt.id 
WHERE       pt.medical_coverage_for = 'dependents_only'
OR          (ac.relationship = 'child' AND ac.age_from::int <= 3 AND ac.age_to::int >= 3  
AND         ac.gender = 'female' AND ac.marital_status = 'single') 
OR          (ac.relationship = 'child' AND ac.age_from::int <= 4 AND ac.age_to::int >= 4  
AND         ac.gender = 'male' AND ac.marital_status = 'single' ) 
OR          (ac.relationship = 'child' AND ac.age_from::int <= 2 
AND         ac.age_to::int >= 2  AND ac.gender = 'female' AND ac.marital_status = 'single')    
GROUP BY    pt.id, 
            pt.plan_name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 2021-08-07
    • 2021-06-30
    • 1970-01-01
    • 2020-02-08
    相关资源
    最近更新 更多