Question

I have a table like this: (Please note that Names are not unique and can be repeated, while Personal_ID is unique).

ID    SourceID     Personal_ID     Name     NumberOfPurchases 
1      4            1001           Alex           10
2      2            1002           Sara            5
3      4            1001           Alex            12
4      1            1003           Mina            200
5      2            1002           Sara            20  
6      2            1001           Alex            64

Now what need to do is to get the total sum of Number of purchases each person had based on given the SourceID. So that we have the results for sourceId = 4 as:

        Name        Total Number of Purchases
 1.     Alex                 22

And for SourceID = 2

        Name        Total Number of Purchases
1.      Alex                 64
2.      Sara                 25

For this I came up with something like this:

SELECT Name,Sum(NumberOfPurchases) AS Total
FROM    tblTEST
GROUP BY (Personal_ID)
HAVING (SOURCEID = @id)

but this is apparently wrong. I am stuck here, if I add other fields to the group-by clause the result would be completely different and if I don't, this select command wont work. How can I achieve such a result?

Was it helpful?

Solution

I would guess that the problem here is that you have Name in your SELECT clause, but you're grouping on Personal_ID. It might help if you add Name explicitly to your GROUP BY clause as well. If all is well, Name will be functionally determined by Personal_ID anyway.

And you should also put the filter on SourceID in the WHERE clause like Lucero says. So your query should look like this:

SELECT   Name
         ,Sum(NumberOfPurchases) AS Total
FROM     tblTEST
WHERE    SOURCEID = @id
GROUP BY Personal_ID, Name;

Check out this Fiddle.

To clear things up: if you use an aggregation function like SUM(), all other things in your SELECT clause should also be in your GROUP BY clause. But you do not want to group only on Name, because it is not unique in your case. That is why you have both Personal_ID and Name in your GROUP BY clause. The query will not execute when Name is missing in the GROUP BY. And you're adding Personal_ID to make sure not all Sara's are put in a big Sara-group, but are grouped according to Personal_ID.

OTHER TIPS

Something like this?

SELECT Name, SUM(NumberOfPurchases) AS Total
FROM tblTEST
WHERE (SourceID = @id)
GROUP BY Name

Note: The WHERE filters before grouping, and HAVING filters after grouping.

You can try with this:

SELECT  names.Name
        , names.Personal_ID
        , grouped.Total
FROM    (
            SELECT  SourceID
                    , Personal_ID
                    , SUM(NumberOfPurchases) AS Total
            FROM    tblTEST
            GROUP BY 
                    SourceID, Personal_ID
) grouped
JOIN    (

        SELECT  DISTINCT
                Personal_ID
                , Name
        FROM    tblTEST
) names ON      names.Personal_ID = grouped.Personal_ID
WHERE           SourceID = @id

Here is an SQL Fiddle

Among test data I added another record that contains person named 'Alex', now there are two persons with same name which shows that grouping cannot be performed using Name column since it is not unique. I also added Personal_ID in the select list so that people with same names could be distinguished.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top