从连接表中查询值的SUM - 返回相乘的结果

时间:2015-01-03 16:27:59

标签: sql sql-server

在我的数据库中,我有表:Job。每个作业都可以包含任务(一对多) - 并且可以在多个作业上重复使用相同的任务。因此,有一个Task表和一个JobTask(多对多关系的联结表)。还有Payment表,用于记录收到的付款(使用JobId列来跟踪付款与哪个作业相关)。可能会有多笔付款归因于某项工作。

使用SQL Server 2012,我有一个查询,返回作业的简短摘要(作业总值,收到的总金额):

select j.JobId,
sum(t.Rate) as [TotalOwedP],
sum(p.Amount) as [TotalReceivedP]

from Job j
left outer join Payment p on j.JobId=p.JobId
left outer join JobTask jt on j.JobId=jt.JobId
left outer join Task t on jt.TaskId=t.TaskId

group by j.JobId

此查询的问题在于它返回的“总收到”金额远高于应有的金额。我必须在这里找到一些可以引起这种情况的东西。

在我的测试数据库中,我有一份工作。这项工作分配了六个任务。它还分配了一笔付款(100英镑 - 存储为10000)。

对此数据使用上述查询时,TotalReceivedP列会显示60000,而非10000。它似乎是分配给工作的每项任务的支付金额倍增。请注意,如果我向此作业添加另一项任务(因此任务数量现为7),TotalReceivedP列会显示70000

我的查询存在明确的问题,但我无法解决它的问题。任何敏锐的眼睛能够发现它吗?似乎连接有问题。

4 个答案:

答案 0 :(得分:2)

使用子选择来计算SUM:

select j.JobId,
sum(t.Rate) as [TotalOwedP],
(SELECT SUM(p.Amount) FROM Payment p WHERE j.JobId=p.JobId) as [TotalReceivedP]
from Job j
left outer join JobTask jt on j.JobId=jt.JobId
left outer join Task t on jt.TaskId=t.TaskId
group by j.JobId

答案 1 :(得分:1)

对于每个单独的JobIdSUM(p.Amount)总结与Task记录相关的每个Job记录的相同金额值JobId。如果6条记录与特定Job相关,则SUM(p.Amount)将计算金额乘以6,如果7条记录相关,则金额乘以7,依此类推。

由于每个作业只有一个付款金额,因此无需在 p.Amount 上执行总和。这样的话会给你想要的结果:

select j.JobId,
       sum(t.Rate) as [TotalOwedP],
       max(p.Amount) as [TotalReceivedP]

from #Job j
left outer join #Payment p on j.JobId=p.JobId
left outer join #JobTask jt on j.JobId=jt.JobId
left outer join #Task t on jt.TaskId=t.TaskId

group by j.JobId

修改

由于使用的平台是SQL Server,因此获得总和聚合的方式非常简洁(IMHO)CTEs

;WITH TaskGroup AS (
   SELECT JobId, SUM(Rate) AS [TotalOwedP]
   FROM #Task t
   INNER JOIN #JobTask jt ON t.TaskId = jt.TaskId
   GROUP BY JobId
), PaymentGroup AS (
   SELECT JobId, SUM(Amount) [TotalReceivedP]
   FROM #Payment
   GROUP BY JobId
)
SELECT tg.JobId, tg.TotalOwedP, pg.TotalReceivedP
FROM TaskGroup tg
LEFT JOIN PaymentGroup pg ON tg.JobId = pg.JobId

我只猜测表架构,但上面应该给你你想要的东西。第一个CTE计算每RateJobId总和,每个Amount的第二个CTE JobId总和,最终查询使用两个CTE将结果放在一个表中。< / p>

答案 2 :(得分:0)

问题是你的JOIN约束必须不够具体,所以你得到的结果行太多了。可能还应该在Task上加入付款?除非你发布所有表格模式,否则无法判断。

答案 3 :(得分:0)

您应该将TotalOwed的查询与TotalReceived的查询分开。 TotalOwed基于各个任务,而付款则与作业相关联,而不是任务。

--first query
select j.JobId,
sum(t.Rate) as [TotalOwedP]
from Job j
left outer join JobTask jt on j.JobId=jt.JobId
left outer join Task t on jt.TaskId=t.TaskId
group by j.JobId

--second query
select j.JobId,
sum(p.Amount) as [TotalReceivedP]
from Job j
left outer join Payment p on j.JobId=p.JobId
group by j.JobId