从具有重复项的连接中的另一个表返回Sum

时间:2014-08-21 16:37:28

标签: sql sql-server ansi-sql

我有以下2个表格:

tblEventCustomers

EventCustomerId EventId CustomerId  InvoiceLineId
1002            100     5           21
1003            100     6           21
1004            100     7           22
1005            101     9           23

tblInvoiceLines

InvoiceLineId   Quantity    Price
21              2           25
22              1           12.5
23              1           34

我想要返回活动中的客户数量以及该活动的发票行总数:

EventId     No. Delegates   Total
100         3               37.5
101         1               34

我尝试过以下功能:

CREATE FUNCTION dbo.udfInvoiceLineTotal
(
    @eventId AS INT
)
RETURNS MONEY
BEGIN
    DECLARE @returnAmount AS MONEY;
    SET @returnAmount = (
    select sum(Price) from tblInvoiceLines as IL
    where il.InvoiceLineId in
    (
        SELECT InvoiceLineId
        FROM tblEventCustomers
        where EventId = @eventId
    )   
    )
    RETURN @returnAmount;
END

并使用如下:

select      ed.EventId, 
            COUNT(1),
            dbo.udfInvoiceLineTotal(ed.EventId) from tblEventCustomers as ED

inner join  tblInvoiceLines as IL
on          IL.InvoiceLineId = ED.InvoiceLineId
group by    ed.EventId

这会返回我想要的结果,但是我想看看我是否错过了以更多ANSI SQL方式进行的任何方式,即使用子查询而不是数据库函数?

下面的方法会在总和中返回重复项:

select  ed.EventId,
        SUM(il.Price),
        COUNT(1)
from    tblEventCustomers as ed
inner join tblInvoiceLines as il
on      ed.InvoiceLineId = il.InvoiceLineId
group by (ed.EventId)

修改

对所有回答的人道歉,我发现我的原始数据集中有一个拼写错误,这意味着一些建议的方法适用于我最初提供的数据集,但不适用于完整的数据集。< / p>

5 个答案:

答案 0 :(得分:1)

这对你有用吗?它得到你正在寻找的结果

SELECT c.EventId, SUM(Quantity), SUM(i.price)
FROM tblInvoiceLines i
   JOIN (SELECT DISTINCT 
         EventId, CustomerId, InvoiceLineId
        FROM tblEventCustomers) c ON i.InvoiceLineId = c.InvoiceLineId
GROUP BY c.EventId

答案 1 :(得分:1)

如果你修改这样的最后一种方法,它应该会给你想要的结果:

select  ed.EventId,
        SUM(il.Price/il.quantity)
from    tblEventCustomers as ed
inner join tblInvoiceLines as il
on      ed.InvoiceLineId = il.InvoiceLineId
group by (ed.EventId)
having COUNT(ed.EventCustomerId) > 5

要包含代表人数,只需添加SUM(il.quantity)

即可

答案 2 :(得分:1)

如果我理解正确,你需要一个子查询来摆脱你所谓的重复项,这是由EventCustomerId列引起的,你不包括在内。

select
  ec.eventid,
  count (ec.CustomerId),
  sum(il.price)

from
  (select
     eventid,
     customerid,
     invoicelineid
   from
     tblEventCustomers
    group by
      eventid,
      customerid,
      invoicelineid)
   EC
inner join tblInvoiceLines IL
  on ec.invoicelineid = il.invoicelineid
group by
  ec.eventid

SQL Fiddle

答案 3 :(得分:0)

您需要在加入前预先汇总结果。您可以使用子查询:

select c.EventId, c.NumCustomers, ci.price
from (select c.EventId, count(*) as NumCustomers
      from tblEventCustomers c
      group by c.EventId
     ) c left join
     (select c.EventId, sum(i.price) as price
      from (select distinct EventId, InvoiceLineId
            from tblEventCustomers c
           ) c join
           tblInvoiceLines i
           on i.InvoiceLineId = c.InvoiceLineId
      group by c.EventId
     ) ci
     on c.EventId = ci.EventId;

令人困惑的是,您必须将customers表加入invoice表以获取事件ID。

答案 4 :(得分:0)

您可能希望查看CTE(公用表表达式),其中您为一个表预先计算/分组,然后根据列将结果与另一个表连接并一起显示结果。它与子查询类似,但我更喜欢CTE,因为它们更容易阅读。

请参阅这些链接作为参考,希望这会有所帮助:

https://www.simple-talk.com/sql/t-sql-programming/sql-server-cte-basics/

http://blogs.msdn.com/b/craigfr/archive/2007/10/18/ctes-common-table-expressions.aspx