PostgreSQL在连接两个表时将列相乘

o4tp2gmn  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(3)|浏览(207)

我有两个类似于这个例子的表(为了清晰起见进行了简化):

  • 家长:*
  1. | id | name | amount | year |
  2. ----------------------------------------
  3. | 101 | Henry | 300 | 2020 |
  4. ----------------------------------------
  5. | 102 | Carol | 100 | 2020 |
  6. ----------------------------------------
  7. | 103 | Tom | 900 | 2020 |
  8. ----------------------------------------

字符串

  • 孩子:*
  1. | id | parent_id | department |
  2. --------------------------------------
  3. | 1 | 101 | finance |
  4. --------------------------------------
  5. | 2 | 101 | hr |
  6. --------------------------------------
  7. | 3 | 101 | it |
  8. --------------------------------------
  9. | 4 | 102 | support |
  10. --------------------------------------


我试图通过以下脚本连接两个表并获取amount字段的总和值,但由于记录101重复了3次,因此总和将是1900而不是1300:

  1. select
  2. sum(p.amount),
  3. count(c)
  4. from parent p
  5. left join child c on c.parent_id = p.id
  6. where p.year = 2020


当我使用下面的查询时,它可以工作,但它给出的count of child为2而不是4,因为它根据其父记录对子记录进行了分组:

  1. SELECT
  2. SUM(p.amount),
  3. COUNT(c)
  4. FROM parent p
  5. LEFT JOIN (
  6. SELECT parent_id
  7. FROM child
  8. GROUP BY parent_id
  9. ) c ON c.parent_id = p.id
  10. WHERE p.year = 2020;


那么,如何解决这个问题呢?

hmtdttj4

hmtdttj41#

此查询联接表,计算每个父项的子记录计数,然后将父项数量和子项计数相加。

  1. SELECT
  2. SUM(p.amount) AS total_amount,
  3. sum(child_count) AS child_count
  4. FROM parent p
  5. LEFT JOIN (
  6. SELECT parent_id, COUNT(*) AS child_count
  7. FROM child
  8. GROUP BY parent_id
  9. ) c ON c.parent_id = p.id
  10. WHERE p.year = 2020

字符串
而您的查询在SELECT子句中使用子查询,这可能效率较低。此外,它不会显式连接表,这可能会导致混淆子计数与父记录的关系。

91zkwejq

91zkwejq2#

如果你的目标是 * 计算一个总数和查尔兹的总数 *,你必须首先计算孩子的数量,然后在第二步中加入。
此查询计算子计数并返回详细数据

  1. with child_count as (
  2. select parent_id, count(*) child_count
  3. from child
  4. group by 1)
  5. select
  6. p.id, p.amount, c.child_count
  7. from parent p
  8. left outer join child_count c
  9. on p.id = c.parent_id
  10. id |amount|child_count|
  11. ---+------+-----------+
  12. 101| 300| 3|
  13. 102| 100| 1|
  14. 103| 900| |

字符串
添加聚合将提供请求的结果

  1. with child_count as (
  2. select parent_id, count(*) child_count
  3. from child
  4. group by 1),
  5. detail as (
  6. select
  7. p.id, p.amount, c.child_count
  8. from parent p
  9. left outer join child_count c
  10. on p.id = c.parent_id)
  11. select sum(amount) amount, sum(child_count) child_count
  12. from detail
  13. amount|child_count|
  14. ------+-----------+
  15. 1300| 4|

展开查看全部
gj3fmq9x

gj3fmq9x3#

我使用了以下方法,并通过提供父表中的正确金额和子表中的计数来修复这个问题:

  1. SELECT
  2. (SELECT SUM(amount) FROM parent WHERE year = 2020),
  3. COUNT(c)
  4. FROM child c;

字符串
注意:由于查询将被转换为HQL,我不能像@SenthilPNathan的答案那样使用JOIN with子句。

相关问题