I have the following table:
ID (int)
EMAIL (varchar(50))
CAMPAIGNID (int)
isSubscribe (bit)
isActionByUser (bit)
This table stores all subscribe and unsubscribe actions on campaigns for a user. These actions can be done by the user itself (isActionByUser = true) or by the administration desk (isActionByUser = false).
I need to get the last action to determine if a user is subscribed or unsubscribed. But keeping in mind that when a user did an unsubscribe action from a campaign, it will have priority on other subscribe actions by the administration desk.
I have found a nice solution to get the lastest record grouped by EMAIL and CAMPAIGNID. But I can't figure out how I do incorporate the requirement that an isActionByUser = true, has absolute priority over records with isActionByUser = false. Also: when the administration desk does an unsubscribe action, it will have priority over a record with (isSubscribe = true and isActionByUser).
Example data:
ID EMAIL CAMPAIGNID ISSUBSCRIBE ISACTIONBYUSER
-----------------------------------------------------------
1 a@aa.com 1 1 0
2 b@bb.com 1 1 0
3 c@cc.com 1 1 0
4 a@aa.com 1 0 1
5 a@aa.com 1 1 0
6 c@cc.com 1 1 1
7 c@cc.com 1 0 0
The expected result would be:
ID EMAIL CAMPAIGNID ISSUBSCRIBE ISACTIONBYUSER
-----------------------------------------------------------
2 b@bb.com 1 1 0
4 a@aa.com 1 0 1
7 c@cc.com 1 0 0
With the following query
select cs1.*
from
[TABLE] cs1
left join
[TABLE] cs2
on
cs1.EM_EMAIL = cs2.EM_EMAIL
and
cs1.EM_CAMPAIGNID = cs2.EM_CAMPAIGNID
and
cs1.id < cs2.id
where cs2.id is null
I' m having the following result:
ID EMAIL CAMPAIGNID ISSUBSCRIBE ISACTIONBYUSER
-----------------------------------------------------------
2 b@bb.com 1 1 0
5 a@aa.com 1 1 0
7 c@cc.com 1 0 0
Another approach:
SELECT *
FROM [TABLE] cs
WHERE id in
(
SELECT top 1 id
FROM [TABLE] ss
WHERE
cs.EMAIL = ss.EMAIL
and
cs.CAMPAIGNID = ss.CAMPAIGNID
and ISSUBSCRIBE = (
select top 1 min(convert(int, ISSUBSCRIBE))
FROM [TABLE] sss
WHERE
cs.EMAIL = sss.EMAIL
and
cs.CAMPAIGNID = sss.CAMPAIGNID
)
and ISACTIONBYUSER= (
select top 1 max(convert(int, ISACTIONBYUSER))
FROM [TABLE] ssss
WHERE
cs.EMAIL = ssss.EMAIL
and
cs.CAMPAIGNID = ssss.CAMPAIGNID
)
)
This will produce the following result:
ID EMAIL CAMPAIGNID ISSUBSCRIBE ISACTIONBYUSER
-----------------------------------------------------------
2 b@bb.com 1 1 0
4 a@aa.com 1 0 1
6 c@cc.com 1 1 1
Which is also not correct. And I'm afraid performance will be a big rpoblem with this approach.
So any ideas how I can solve this?