如何通过内部连接使用 group by
Posted
技术标签:
【中文标题】如何通过内部连接使用 group by【英文标题】:how to use group by with inner join 【发布时间】:2017-05-19 16:02:26 【问题描述】:我有三张表customer、bargains和installment。 我想从 customer 表中选择 name 并从 bargains 表中选择 total price 的总和以及 的总和根据每个客户从分期付款表中的付款金额,最后从付款金额的总和中减去总价格的总和。 所以结果应该是一个包含所有客户名称及其债务的列表。
我尝试了以下命令,但它返回错误的值,看起来它们相加了两次或更多。
select c.name, b.total_price, i.payment_amount
from customer as c
inner join (select sell_or_buy, sum(total_price) as total_price from bargains group by C_ID ) as b on (b.sell_or_buy = 'خرید')
inner join (select trade_type, sum(payment_amount) as payment_amount from installment group by C_ID ) as i on (i.trade_type = 'پرداخت')
group by c.C_ID
因为我认为查询总和每条分期付款表记录的总价格和总和每条讨价还价表记录的付款金额我尝试在内部连接中使用选择来使它们中的每一个都不同但它不起作用 所以我什至无法减去结果。 我也尝试以下查询
select
(select sum(payment_amount) as payment_amount from installment where trade_type = 'پرداخت'group by C_ID)-
(select sum(total_price) as total_price from bargains where sell_or_buy = 'خرید' group by C_ID)as result
表示查询返回多行的显示和错误。 当我从上面的查询中只使用一个选择时,结果是好的,但是当我尝试组合它时它不起作用。
【问题讨论】:
【参考方案1】:您的原始查询似乎缺少正确的连接条件。试试这个:
select c.name,
b.total_price,
i.payment_amount
from customer as c
inner join
(
select C_ID, sum(total_price) as total_price
from bargains
where sell_or_buy = 'خرید'
group by C_ID
) as b
on c.C_ID = b.C_ID
inner join
(
select C_ID, sum(payment_amount) as payment_amount
from installment
where trade_type = 'پرداخت'
group by C_ID
) as i
on c.C_ID = i.C_ID
如果你想计算总价和支付金额之间的差额,那么就用这个SELECT
:
select c.name,
b.total_price,
i.payment_amount,
b.total_price - i.payment_amount AS diff
【讨论】:
我只想知道哪个更好,减去这两个内部连接在 sql 中的结果,这样我就有两列作为结果(客户名称和债务),正如我提到的问题或当我在 php 中接收查询结果,然后在循环中逐行减去它们。如果第一选择更好,那么我应该怎么做,因为我是 sql 新手,但我可以在 php 中做到这一点【参考方案2】:不需要使用子查询,只需将三张表连接起来做聚合,试试如下:
select
c.name,
sum(b.total_price) as total_price,
sum(i.payment_amount) as payment_amount
from customer as c
inner join bargains b on c.c_id = b.c_id and b.sell_or_buy = 'خرید'
inner join installment i on c.c_id = i.c_id and i.trade_type = 'پرداخت'
group by c.c_id -- ,c.name
就像@Tim Biegleisen 所说,如果您的mysql 数据库的sql_mode
包含ONLY_FULL_GROUP_BY
,您还应该在group by
子句中添加c.name
。
并使用此查询检查sql_mode
:
show variables like 'sql_mode';
【讨论】:
【参考方案3】:你能给我一张每个表的实际屏幕截图,其中包含一些条目吗?
由于这一行,您可能会得到重复的行: inner join (select trade_type, sum(payment_amount) as payment_amount from installment group by C_ID )
基本上,您可能不应该使用 sum() 函数同时从任何其他字段中选择值。原因如下: sum(payment_amount) 应该正确返回 1 行?但是在它旁边你有“select trade_type”,它可能会返回多行。
另外,这是什么语言? MySQL? SQL?
【讨论】:
【参考方案4】:子查询:
SELECT c.Id AS CustomerId, c.Name AS CustomerName, m.Name AS ManagerName, o.SumAmmount
FROM Customers AS c
INNER JOIN Managers AS m ON c.ManagerId = m.Id
INNER JOIN
(SELECT SUM(Amount) AS SumAmmount, o.CustomerId
FROM Orders AS o
WHERE Date >= '2017-01-01'
GROUP BY CustomerId
HAVING SUM(Amount) >= 10000) AS o ON c.Id = o.CustomerId
没有子查询:
SELECT c.Id AS CustomerId, c.Name AS CustomerName,
m.Name AS ManagerName, SUM(o.Amount) AS SumAmmount
FROM Customers AS c
INNER JOIN Managers AS m ON c.ManagerId = m.Id
INNER JOIN Orders AS o ON c.Id = o.CustomerId
WHERE o.Date >= '2017-01-01'
GROUP BY c.Id, c.Name, m.Name
HAVING SUM(Amount) >= 10000
【讨论】:
以上是关于如何通过内部连接使用 group by的主要内容,如果未能解决你的问题,请参考以下文章
如何连接具有不同 GROUP BY 级别的两个查询,使一些记录为空