【问题标题】:Sum value is too big when adding a another table ORACLE SQL添加另一个表ORACLE SQL时Sum值太大
【发布时间】:2021-07-24 13:24:02
【问题描述】:
select NVL((select name from supplier where id = t.id_supplier), 'All suppliers') as suppliers,  
        NVL((select name from stadium where id = m.id_stadium), 'All stadium') as stadium,   
        NVL((select name from league where id = m.id_league), 'All league') as league, 
        (NVL(sum(b.price), 0) + sum(t.cost)) as incomes
FROM match m
inner join ticket b on m.id = b.id_match
inner join stadion s on s.id = m.id_stadium
inner join league l on l.id = m.id_league
inner join transmission t on t.id = m.id_transmission
inner join supplier d on d.id = t.id_supplier
group by cube(d.id, s.id, l.id);

当我想将两个不同表格中的两个值相加时 - 比赛中售罄的门票和电视传输我得到的结果总和值太大。我发现单场比赛的传输成本太大了 X 倍,其中 X 是这场比赛的门票数量,只有当我加入门票表时。 我该如何修复它?

我在这里找到了类似问题的解决方案:SQL: After joining tables SUM() function returns wrong value 但它不适用于立方体。

例如,匹配 id 1 的 bilets 总和为 410.5:

select sum(b.price) from match m
inner join ticket b on m.id = b.id_match
where m.id = 1;

给出的结果 410.5 非常正确。 传输的总和是300 000:

select sum(t.cost) from match m
inner join transmission t on m.id_transmission = t.id
where m.id = 1;

它也返回正确的值。 但是当我添加一张票表时,我得到了 1200410,5 值什么是不正确的:

select sum(t.cost) + sum(b.price) from match m
inner join transmission t on m.id_transmission = t.id
inner join ticket b on b.id_match= m.id
where m.id = 1;

正确的值应该是 300410.5。

【问题讨论】:

  • 我建议您提供示例数据和所需的结果。我怀疑cube 与关闭聚合无关。并且您可以简化查询以更好地说明问题。
  • @GordonLinoff 我添加了其他信息以发布。谢谢你的建议。
  • sum(t.cost) + sum(b.price) 将不起作用,因为两个求和查询都将返回不同的行,并且总和将被添加磨损。例如,成本查询有 3 行和价格查询有 5 行,那么成本查询将被添加 5 次而不是 3 次。

标签: sql oracle


【解决方案1】:

阅读您的问题后,以下查询给出的结果 410.5 非常正确,但计数返回 4(本场比赛的门票数)

   select sum(b.price), count(*) as cnt from match m
   inner join ticket b on m.id = b.id_match
   where m.id = 1;

第二个查询返回 300 000,计数返回 1(仅传输一次)

select sum(t.cost), count(*) cnt from match m
inner join transmission t on m.id_transmission = t.id
where m.id = 1;

当您连接 3 个表时,您现在有 4 行用于最后一个查询(传输),而不仅仅是预期的 1 行。这就是为什么你发现单场比赛的传输成本太大了 X 倍,其中 X 是这场比赛的门票数量。运行以下查询进行验证

select m.id_transmission, cost  from match m
inner join transmission t on m.id_transmission = t.id
inner join ticket b on b.id_match= m.id
where m.id = 1;
ID_TRANSMISSION COST
5 300000
5 300000
5 300000
5 300000

因此,解决方案是加入聚合查询而不是单个表。下面是一个使用 SQL WITH 语法构建子查询的示例

with agg_ticket as (select id_match, sum(b.price) as price from ticket b group by id_match) 
select sum(t.cost) + sum(b.price)  from match m
inner join transmission t on m.id_transmission = t.id
inner join agg_ticket  b on b.id_match= m.id
where m.id = 1;

如果传输查询的计数返回大于1(计数>1),您还需要创建一个子查询

with agg_ticket as (select id_match, sum(b.price) as price from ticket b group by id_match) ,
     agg_transmission as (select id, sum(t.cost) as cost from transmission t group by id)
select sum(t.cost) + sum(b.price)  from match m
inner join agg_transmission t on m.id_transmission = t.id
inner join agg_ticket  b on b.id_match= m.id
where m.id = 1;

这会返回正确的值 300410.5

然后,你可以添加多维数据集语法,我没有所有的表和数据来测试

with agg_ticket as (select id_match, sum(b.price) as price from ticket b group by id_match) ,
     agg_transmission as (select id, sum(t.cost) as cost from transmission t group by id)
select nvl(CAST (m.id AS VARCHAR2(2000)), 'ALL MATCHS') as idMatch,
m.id,
sum(t.cost) + sum(b.price)  from match m
inner join agg_transmission t on m.id_transmission = t.id
inner join agg_ticket  b on b.id_match= m.id
group by cube (m.id);

希望对你有帮助

顺便说一句,如果您遇到以下错误:ORA-00979: not a GROUP BY expression when running this query

select NVL((select name from supplier where id = t.id_supplier), 'All suppliers') as suppliers,  
        NVL((select name from stadium where id = m.id_stadium), 'All stadium') as stadium,   
        NVL((select name from league where id = m.id_league), 'All league') as league, 
        (NVL(sum(b.price), 0) + sum(t.cost)) as incomes
FROM match m
inner join ticket b on m.id = b.id_match
inner join stadion s on s.id = m.id_stadium
inner join league l on l.id = m.id_league
inner join transmission t on t.id = m.id_transmission
inner join supplier d on d.id = t.id_supplier
group by cube(d.id, s.id, l.id);

这是因为,您必须在 SELECT 中使用 group by cube 中使用的相同列。因为您正在使用 SELECT 表达式执行 NVL,所以请注意 NVL 表达式中的 WHERE 子句

NVL((select name from league where id = l.id), 'All league') as league

而不是

NVL((select name from league where id = m.id_league), 'All league') as league

即使 l.id = m.id_league 你正在按立方体进行分组(d.id, s.id, l.id);

在您的情况下,我建议修改 GROUP BY 并保留 SELECT :

group by cube(t.id_supplier, m.id_stadium, m.id_league);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 2021-11-24
    • 2015-01-29
    • 2015-07-06
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多