Search code examples
sqlsql-serveransi-sql

Return Sum from another table in join with duplicates


I have the following 2 tables:

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

I want to return the number of customers on an event and the total of the invoice lines for that event:

EventId     No. Delegates   Total
100         3               37.5
101         1               34

I have tried the following function:

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

And used it as below:

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

This returns me the results I want, however I wanted to see if I was missing any way to do it in a more ANSI SQL way, i.e. using Sub-Queries rather than a database function?

The approach below returns me duplicates in the sum:

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)

Edit

Apologies for all those who answered, I realise I had a typo in my original data set which meant some of the suggested approaches worked for the dataset I presented at first but don't work for the full data set.


Solution

  • If you modify your last approach like this, it should give you the desired results:

    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
    

    And to include the number of delegates, just add SUM(il.quantity)