【问题标题】:MySQL distinct sum without subqueries没有子查询的 MySQL 不同总和
【发布时间】:2014-02-01 21:55:58
【问题描述】:

我有两个主表 bills 和 billing_items:

bills
_______
id
..
amount
balance

billing_items
______________
id
...
bill_id

我需要根据 billing_items 表中的某些条件获取账单金额和余额的总和(该表引用了其他感兴趣的表)

当我使用以下查询时,我得到了重复:

select sum(b.amount), sum(b.balance) 
from bills b left join billing_items bi 
on b.id=bi.bill_id;

由于我使用的是 ORM,我无法使用如下子查询(不支持子查询):

select sum(a) from 
(select b.amount as a, b.balance 
   from bills b left join billing_items bi 
   on b.id=bi.bill_id group by b.id) t;

billing_items 及其引用表的标准被省略,但我需要引用 billing_items

【问题讨论】:

  • 考虑提供适当的 DDL 和/或 sqlfiddle 以及所需的结果集
  • 那么第一个查询有什么问题呢?您能否解释一下“某些标准”是什么(因为您的查询中没有任何过滤器)。我认为,如果您能用通俗易懂的语言解释您希望结果集是什么样子,那将非常有帮助。
  • 我将在内部加入 billing_items 与其他 3 个表(访问过程 -> 访问 -> 推荐人 -> 公司)我需要过滤 company.id
  • VIEWS 不理想,我需要一个代码更改最少的解决方案
  • 你能在你的 SQL 和 ORDER BY 中使用@variables 吗?这可能是一个解决方案。

标签: mysql sql


【解决方案1】:

不确定你的 ORM 是否允许在你的 SQL 中使用用户变量,如果是,你可以试试这个,基本上是 ORDER BY bi.bill_id 并且只有在有新的 bill_id 时才总和

select sum(IF (@prevBillId IS NULL OR @prevBillId != bi.bill_id,b.amount,0)) as sumAmount, 
       sum(IF (@prevBillId IS NULL OR @prevBillId != bi.bill_id,b.balance,0)) as sumBalance,
       @prevBillId:=bi.bill_id
from bills b left join billing_items bi 
on b.id=bi.bill_id
ORDER BY bi.bill_id;

看到这个sqlFiddle

【讨论】:

  • ORM 没有,但这是一个很好的解决方案。可惜我不能用它
  • 您的 ORM 是否允许您使用 NOT EXIST(SELECT from sometable WHERE somecolumn=somevalue)?
【解决方案2】:

希望这会奏效...

因此,您的问题是您对 billing_items 的左连接导致每个计费项目多行,并且您的 sum(b.amount) 乘以您拥有的行数。所以解决方案...用你的计数除以你的总和。

select b.id,sum(b.amount) / count(*) as amount, sum(b.balance) 
from bills b left join billing_items bi 
on b.id=bi.bill_id;
group by b.id

试一试...希望成功。

【讨论】:

  • 我喜欢这个主意,但它行不通。为每个特定账单中的每个计费项目再次添加每个账单的金额
  • 账单表中的合计金额正确吗?当您加入 billing_items 时,只需为每个计费项目(或每一行)重复账单金额。不知道我是否明白为什么它不能工作。如果 10'000 重复多次,则总和为 40000,除以 4 即可返回您想要的 10'000 数字。也许我不明白你在这里总结什么
  • ((100 + 100 + 100) / 3)) + ((200 + 200 + 200 + 200)/4) != 1100/7
  • 我在我的解决方案中错过了一个分组...在更改中进行了编辑。您想按 b.id 分组以保持 3 100 和 4 200 按 ID 分开。
  • 是的,但这不会给出单行结果
猜你喜欢
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多