You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Inner Join时避免笛卡尔积,确保sum(tbl2_amt)计算准确

问题

我正在处理一个需要关联table1与table2的业务场景,但因需包含特定字段,导致sum(tbl2_amt)的计算结果为实际值的3倍。

表结构及数据

Table1

col1    col2    col3    period  col4    col5    col6    col7    tbl1_amt
20110   dt      0000    202302  tcp             de      otfx    19169.19495
20110   dt      0000    202302  tcp             de      acpy    416134.8921
20110   dt      0000    202302  tcp             de      forx    -114689.5469

Table2

period  col1    col2    col3    col4    tbl2_amt
202302  20110   dt      0000    1711    31172.64171
202302  20110   dt      0000    1290    470.1353638
202302  20110   dt      0000    1208    -157.4978849
202302  20110   dt      0000    8158    18382.71997
202302  20110   dt      0000    1200    388217.7242
202302  20110   dt      0000    1200    290454.7377
202302  20110   dt      0000    1290    9422.588832
202302  20110   dt      0000    1711    505307.5402
202302  20110   dt      0000    1290    9980.002115
202302  20110   dt      0000    1290    139973.5195
202302  20110   dt      0000    0000    513661.3896
202302  20110   dt      0000    1200    138179.7272
202302  20110   dt      0000    1200    7159.475465
202302  20110   dt      0000    1236    268.0203046
202302  20110   dt      0000    1290    -480.3828257
202302  20110   dt      0000    1711    11272.73689
202302  20110   dt      0000    1200    1.057529611
202302  20110   dt      0000    1711    2084.263959
202302  20110   dt      0000    1711    3142.110829
202302  20110   dt      0000    1712    23.19162437
202302  20110   dt      0000    8307    11835.60702
202302  20110   dt      0000    1057    1230.964467
202302  20110   dt      0000    1903    271644.247
202302  20110   dt      0000    1290    2470.642978
202302  20110   dt      0000    1057    46684.64467
202302  20110   dt      0000    1290    23518.40102
202302  20110   dt      0000    1290    66276.70262
202302  20110   dt      0000    1290    244284.5812
202302  20110   dt      0000    1903    105582.0749
202302  20110   dt      0000    1290    196.4890017
202302  20110   dt      0000    1208    891.4974619
202302  20110   dt      0000    1711    288288.1557
202302  20110   dt      0000    1200    13.21912014
202302  20110   dt      0000    1200    2310.7022
202302  20110   dt      0000    1290    23006.66244
202302  20110   dt      0000    1185    32263.95939
202302  20110   dt      0000    1200    55201.96701
202302  20110   dt      0000    1299    156910.4484
202302  20110   dt      0000    1711    161.178088
202302  20110   dt      0000    1290    308384.6975
202302  20110   dt      0000    1057    3162.182741
202302  20110   dt      0000    1290    694.4585448
202302  20110   dt      0000    1200    262519.9979
202302  20110   dt      0000    1711    469633.0372

原SQL查询

Select 
    tbl1.period, 
    tbl1.col1, 
    tbl1.col2, 
    tbl1.col3, 
    tbl1.col4, 
    tbl1.col5, 
    tbl1.col6, 
    tbl1.col7, 
    tbl2.col4, 
    sum(tbl2_amt) 
from 
    tbl1 
join tbl2 
on tbl1.col1 = tbl2.col1
and tbl1.col2 = tbl2.col2
and tbl1.col3 = tbl2.col3
and tbl1.period = tbl2.period
group by tbl1.period, tbl1.col1, tbl1.col2, tbl1.col3, tbl1.col4, tbl1.col5, tbl1.col6, tbl1.col7, tbl2.col4

当前查询中sum(tbl2_amt)的结果是实际值的3倍,需要在获取tbl2.col4、tbl1.col7的同时,确保sum(tbl2_amt)计算准确,避免结果翻倍。

解决方案

问题根源是:Table1中有3条同col1/col2/col3/period的记录,每条都会与Table2中匹配的记录关联,导致Table2的每条记录被重复计算3次,最终sum结果是实际值的3倍。

要解决这个问题,需先对Table2按分组维度聚合得到准确sum值,再与Table1关联,具体有两种实现方式:

方法一:使用CTE先聚合Table2

-- 先计算Table2各维度的准确sum(tbl2_amt)
WITH tbl2_agg AS (
    SELECT 
        period, col1, col2, col3, col4,
        SUM(tbl2_amt) AS total_tbl2_amt
    FROM tbl2
    GROUP BY period, col1, col2, col3, col4
)
-- 关联Table1获取所需字段
SELECT 
    tbl1.period, 
    tbl1.col1, 
    tbl1.col2, 
    tbl1.col3, 
    tbl1.col4, 
    tbl1.col5, 
    tbl1.col6, 
    tbl1.col7, 
    tbl2_agg.col4, 
    tbl2_agg.total_tbl2_amt
FROM tbl1
JOIN tbl2_agg 
    ON tbl1.col1 = tbl2_agg.col1
    AND tbl1.col2 = tbl2_agg.col2
    AND tbl1.col3 = tbl2_agg.col3
    AND tbl1.period = tbl2_agg.period

方法二:使用子查询替代CTE(兼容不支持CTE的数据库)

SELECT 
    tbl1.period, 
    tbl1.col1, 
    tbl1.col2, 
    tbl1.col3, 
    tbl1.col4, 
    tbl1.col5, 
    tbl1.col6, 
    tbl1.col7, 
    tbl2_sub.col4, 
    tbl2_sub.total_tbl2_amt
FROM tbl1
JOIN (
    SELECT 
        period, col1, col2, col3, col4,
        SUM(tbl2_amt) AS total_tbl2_amt
    FROM tbl2
    GROUP BY period, col1, col2, col3, col4
) AS tbl2_sub
    ON tbl1.col1 = tbl2_sub.col1
    AND tbl1.col2 = tbl2_sub.col2
    AND tbl1.col3 = tbl2_sub.col3
    AND tbl1.period = tbl2_sub.period

说明

两种方法都是先对Table2按period/col1/col2/col3/col4计算出准确的sum值,再与Table1关联,这样Table2的每条聚合结果只会和Table1的匹配记录关联一次,既避免了重复计算,又保留了tbl2.col4和tbl1.col7字段。

内容的提问来源于stack exchange,提问作者djm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:50:58