sql - 添加另一个表ORACLE SQL时Sum值太大
问题描述
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:加入表后 SUM() 函数返回错误值 ,但它不适用于多维数据集。
例如,匹配 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。
解决方案
阅读您的问题后,以下查询给出的结果 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 | 成本 |
---|---|
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你正在做 group by cube(d.id, s.id, l.id );
在您的情况下,我建议修改 GROUP BY 并保留 SELECT :
group by cube(t.id_supplier, m.id_stadium, m.id_league);
推荐阅读
- google-apps-script - 从 http 源加载 TEX 扩展失败
- liferay - Liferay 7 - 我需要使模拟用户 URL 动态化
- javascript - 的背景在它之后留出空间,当我试图缩小屏幕时
- html - 我需要无法通过 html.Parse() 解析的 HTML
- python - 带有条件的ansible中的json查询
- javascript - 如何选择包含引号的元素?
- spring - 异步 Spring Batch。通过 2 个步骤创建工作
- angular - 如何防止工具栏上的扩展面板溢出?
- r - 取一行中的第一个和最后一个观察值之间的差异,其中每一行都不同
- javascript - 如何使用 react-navigation 进行条件路由?