Reputation: 49
My Google-fu is coming up short on this one. I've got a table of transactions, like this:
id email source amount timestamp
1 [email protected] vendor 10 2014-03-10 23:34:40
2 [email protected] website 15 2014-03-11 13:30:00
3 [email protected] website 50 2014-03-11 17:30:00
4 [email protected] website 65 2014-03-13 20:06:30
5 [email protected] vendor 10 2014-03-14 16:20:30
I want to be able to group these by email, but only for users who:
A) came in through the 'vendor' source initially, and
B) also made a transaction through the 'website' source.
So for the above sample data, I would want this:
email total_amount transactions
[email protected] 75 2
Mary would not be included because her first transaction was through 'website', and not 'vendor'. John would not be included because he did not have a transaction through the vendor at all.
EDIT:
Less ideal, but still useful, would be this result set:
email total_amount transactions
[email protected] 75 2
[email protected] 60 2
Where Mary and Daniel are both included because they both came in through the 'vendor' source in at least one transaction.
Upvotes: 0
Views: 43
Reputation: 6525
Try this :-
select x1.email_id,(x1.tot + x2.tot)as total_amount,(x1.cnt + x2.cnt)as transactions from
(select t1.email_id,count(t1.email_id)as cnt,sum(t1.totalamt)as tot from testdata t1 where t1.sourcee='web' group by t1.email_id)x1
inner join (select t2.email_id,count(t2.email_id)as cnt,sum(t2.totalamt)as tot from testdata t2 where t2.sourcee='vendor' group by t2.email_id)x2
on x1.email_id=x2.email_id group by x1.email_id;
Output :-
Its working fine.If required you please change the field name as per your table structure. Hope it will help you.
Upvotes: 0
Reputation: 6315
This query should give you the desired result by using a subquery to find the persons that have an initial 'vendor' record followed by a 'website' record, before collecting the summary information from the records for these persons.
If you remove the lines marked with -- *
, persons whose 'vendor' record is not their first one is also included.
SELECT email, SUM(amount) AS total_amount, COUNT(*) AS transactions
FROM transactions
WHERE email IN
(SELECT t1.email FROM transactions t1
LEFT JOIN transactions t0 -- *
ON t0.email = t1.email AND t0.timestamp < t1.timestamp -- *
LEFT JOIN transactions t2
ON t2.email = t1.email
WHERE t1.source = 'vendor' AND t2.source = 'website'
AND t0.email IS NULL -- *
)
GROUP BY email;
See http://www.sqlfiddle.com/#!2/864898/8/0
Upvotes: 1
Reputation: 35323
SELECT A.Email, sum(B.Amount) as Total_Amount, count(B.time) as Transactions
FROM tableName A
INNER join tableName B
on A.Email=B.Email
AND A.source='vendor'
Group By A.Email
Requirements are a bit unclear as you initially indicate the must initially come though vendor, but then you retract that statement later by adding mary.
http://sqlfiddle.com/#!2/bb4f9/1/0
If date/timestamps are important add an AND clause for A.Time<= B.Time and aggregrate the A.Amoun t and A.time and add those in like...
SELECT A.Email, sum(B.Amount)+ sum(A.Amount) as Total_Amount, count(B.time)+count(A.Time) as Transactions
FROM tableName A
INNER join tableName B
on A.Email=B.Email
AND A.source='vendor'
and A.Time<=B.Time
Group By A.Email
But this assumes vendor entry will only occur once for each email
So this solution first finds a vendor entry (if there's more than one for an email address this will not return accurate counts) then it finds any entries for the same email address with a source of website occurring after that vendor entry and aggregates the totals for that email adding in the vendor entry totals. While it works for the same data provided, it may not work as desired if multiple vendor entries exist for the same email. Without understanding how the totals should occur or if multiple data exists, or understanding why you need this information based on this data, I can't think of a better option without making lots of assumptions.
SELECT A.Email, sum(B.Amount)+sum(A.Amount) as Total_Amount,
count(B.time)+count(A.Time) as Transactions
FROM tableName A
INNER join tableName B
on A.Email=B.Email
AND A.source='vendor'
AND A.Time < B.Time and B.Source='website'
Group By A.Email
Upvotes: 2
Reputation: 5271
Your query should look like this :
select email, sum(amount) ,count(*)
from tbl
where email='[email protected]'
group by email;
OR - to count all email !
select email, sum(amount) ,count(*)
from tbl
group by email;
All by vendor
select email, sum(amount) ,count(*)
from tbl
where source ='vendor'
group by email;
Also demo here: http://sqlfiddle.com/#!2/de36ed/2
Upvotes: 0