Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Help with Query (joins, sum) pt 2

Author  Topic 

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-10 : 18:45:23

Hi,

As it was recommended to me I've changed my database design for this question. I'll repost with sample data and new table structure now.


tblUsers (stores the users info and userID)
tblAffils (stores each affiliates info and the related field affilID)
tblTransactions (stores transactions of each user and fields userID, membershiptype)
tblAffilUsers(stores each affilID for users that register with an
affil)

Here is some sample data:

[tblUsers]
userID, password
500, username
501, username
502, username
503, username
504, username

[tblAffils]
affilID, password
2, password
3, password
4, password

[tblAffilUsers]
userID, affilID

500, 2
503, 3
504, 3

[tblTransactions]
userID, membershipType, datestart, dateEnd

500, 2, 01/01/2000, 01/01/2010
503, 3, 01/01/2000, 01/01/2010
504, 3, 01/01/2000, 01/01/2010

Running lifetime stats against affiliate 3 should return

affilID, freesignups, level2signups, level1signups, date


I need to run a SP that returns data for each Affiliate. I need to be able to get stats for a certain date, or for range of dates.

I need to know the total number of signups each affiliate has, which is the count of total users with their affiliateID.

The ultimate goal of this SPROC is to determine how much money each affiliate brings in, which means the number of sales has to be determined. Currently there are 4 different levels of membership that can be purchased, all with different pricing.

In the transaction table, all sales are recorded. I need to join on the number of the day's sales for each type of membership. I need the date the sale was made on to line up with the date selected. By this I mean, if the user joins August 1st, and converts to a paying person by the 9th. This should count as a sale on the 9th, not first.

Ideally, this report would show the results with a row for each date and total and then a grand total at the end.

I hope this is fairly clear, if theres anything I can explain better please let me know.

Thanks alot for any assistance,

Mike123

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-10 : 19:09:17
I guess [tblUsers] should contain fields userID and username instead of userID and password
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-10 : 19:25:00
is [tblAffilUsers].affilID same as [tblTransactions].membershipType?
Can you explain freesignups, level2signups, level1signups
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-10 : 20:03:25
quote:
Originally posted by mk_garg20

is [tblAffilUsers].affilID same as [tblTransactions].membershipType?
Can you explain freesignups, level2signups, level1signups



Hi mk_garg20,

tblAffilUsers.affilID is not the same as [tblTransactions].membershipType.

There are currently 4 types of memberships.

I need to track the total # of people who signup and do not have a record in the tblTransactions(free signups).

For the people who do have a record in the tblTransactions, there are 4 different types of memberships they could have purchased. I need a column for each type.

Example

Affil ID 5 could have these stats

Free signsup , level1 sales, level2 sales, level3 sales, level4sales,
100, 5, 2, 1, 9


Hope that helps.

Thanks again,
mike123

Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-11 : 01:36:18
Hi Mike,
Check this code.

create table #tblUsers(userID int, username varchar(20))
insert into #tblUsers
select 500, 'username500'
UNION ALL
select 501, 'username501'
UNION ALL
select 502, 'username502'
UNION ALL
select 503, 'username503'
UNION ALL
select 504, 'username504'

create table #tblAffils(affilID int, password varchar(20))
insert into #tblAffils
select 2, 'password2'
UNION ALL
select 3, 'password3'
UNION ALL
select 4, 'password4'

create table #tblAffilUsers(userID int, affilID int)
insert into #tblAffilUsers
select 500, 2
UNION ALL
select 501, 2
UNION ALL
select 503, 3
UNION ALL
select 504, 3

create table #tblTransactions(userID int, membershipType int, datestart datetime, dateEnd datetime)
insert into #tblTransactions
select 500, 2, '01/01/2000','01/01/2010'
UNION ALL
select 503, 3, '01/01/2000', '01/01/2010'
UNION ALL
select 504, 3, '01/01/2000', '01/01/2010'


select affilid,
sum(case when membershiptype=0 then total else 0 end) as freesales,
sum(case when membershiptype=2 then total else 0 end) as level2sales,
sum(case when membershiptype=3 then total else 0 end) as level3sales
from
(select #tblAffilUsers.affilID as affilid,
isnull(#tblTransactions.MembershipType,0) as membershiptype,
count(#tblAffilUsers.affilID) as total
from #tblAffilUsers LEFT JOIN #tblTransactions ON #tblAffilUsers.userID=#tblTransactions.userID
GROUP BY affilID, MembershipType) as tbla
group by affilid order by affilid

drop table #tblUsers
drop table #tblAffils
drop table #tblAffilUsers
drop table #tblTransactions

Am i closer to your requirement.

Cheers
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-11 : 02:05:28
Hi mk_garg20,

Looks great so far!. Except one thing.

A "Free" signup has no row in the tblAffilUsers table. I redesigned it as you suggested. How can I modify this query to accomodate that?

Thanks once again , really appreciated.

mike123
Go to Top of Page

ffoiii
Starting Member

12 Posts

Posted - 2004-08-11 : 14:52:11
Mike,

I may have misunderstood your original query (from first thread), in that I thought some users could signup without being referred by an affiliate, not that some users could sign up for free.

As such, if _every_ user comes from/through an affiliate, there is no need for a separate tblUserAffil, and you can just set AffilID in tblUser. Additionally, although there is no dollar amount assoicated with the "transaction", you may still want to add a record to Transaction even if MembershipType is 'Free'.

It's difficult to give advice re schema design without extensive conversations regarding the usage and rules of the application. That's why Data Architects have a job!


ffoiii
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-11 : 17:01:11
quote:
Originally posted by ffoiii

Mike,

I may have misunderstood your original query (from first thread), in that I thought some users could signup without being referred by an affiliate, not that some users could sign up for free.

As such, if _every_ user comes from/through an affiliate, there is no need for a separate tblUserAffil, and you can just set AffilID in tblUser. Additionally, although there is no dollar amount assoicated with the "transaction", you may still want to add a record to Transaction even if MembershipType is 'Free'.

It's difficult to give advice re schema design without extensive conversations regarding the usage and rules of the application. That's why Data Architects have a job!


ffoiii



Hi foii,

Sorry if I was unclear, your actually correct but I'll clarify things here further.

Users can signup with or without an affiliate referal. Everyone signs up for free to start.

I am looking to track what the users that sign up under each affiliate do. Some will stay with their free account, some will choose to upgrade to a pay account.

Altho many will sign up without a referal, I'd still like to be able to query all referalless signups if that makes sense. This is not as crucial and won't be run as often tho.

Hopefully with that information you can help me a bit more :)

Thanks once again

mike123

Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-11 : 18:43:31
quote:
Originally posted by mike123

Hi mk_garg20,

Looks great so far!. Except one thing.

A "Free" signup has no row in the tblAffilUsers table. I redesigned it as you suggested. How can I modify this query to accomodate that?

Thanks once again , really appreciated.

mike123



quote:
Originally posted by mike123

Example

Affil ID 5 could have these stats

Free signsup , level1 sales, level2 sales, level3 sales, level4sales,
100, 5, 2, 1, 9




Mike at one place you are saying free signups dont have any record in tblAffilUsers and your example is showing free sign ups for affil id. how is it possible.

Please clarify this.

Cheers
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-11 : 18:58:59
Hi mk_garg20,

Sorry for the confusion.

I meant a free signup has no row in the "tblTransaction" table, since they did not buy anything.

All signups can have an affilID or no affilID, depends if they were referred or not. If they have an affilID its stored in the [tblAffilUsers] table.

When a member upgrades their account, a row will be placed in the tblTransactions table, with their membershiptype.


Again, sorry for the confusion. I've read it over I dont think Im contradicting myself anymore :)

Thanks for your patience, :)
mike123
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-13 : 20:47:57
bump, can anyone lend a hand to me on this one ?

if so, its greatly appreciated.

mike123
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-08-15 : 07:04:40
I would have to say that I totally agree with "ffoiii" that the table tblAffilUsers is totally useless as one person only can have one affiliate (I assume this is the case??). Affiliate should therefore be a nullable attribute to tblUsers instead...I don't think it will make things any easier but having a table by it's own for this purposedoesn't make sense. I modified the code mk_garg20 had made so it also counts those that have no affiliate (notice that user 502 and 505 has NULL as their affiliate):
DECLARE @tblUsers table (userID int, username varchar(20), affilID int)
insert into @tblUsers
select 500, 'username500', 2 UNION ALL
select 501, 'username501', 2 UNION ALL
select 502, 'username502', NULL UNION ALL
select 503, 'username503', 3 UNION ALL
select 504, 'username503', 3 UNION ALL
select 505, 'username504', NULL

DECLARE @tblAffils table (affilID int, password varchar(20))
insert into @tblAffils
select 2, 'password2' UNION ALL
select 3, 'password3' UNION ALL
select 4, 'password4'

DECLARE @tblTransactions table
(userID int, membershipType int, datestart datetime, dateEnd datetime)
insert into @tblTransactions
select 500, 2, '01/01/2000','01/01/2010' UNION ALL
select 500, 2, '01/01/2000','01/01/2010' UNION ALL
select 500, 3, '01/01/2000','01/01/2010' UNION ALL
select 502, 3, '01/01/2000','01/01/2010' UNION ALL
select 503, 3, '01/01/2000', '01/01/2010' UNION ALL
select 504, 3, '01/01/2000', '01/01/2010' UNION ALL
select 505, 2, '01/01/2000', '01/01/2010'

select affilid,
sum(case when membershiptype = 0 then total else 0 end) as freesales,
sum(case when membershiptype = 2 then total else 0 end) as level2sales,
sum(case when membershiptype = 3 then total else 0 end) as level3sales
from
(select isnull(a.affilID, 0) as affilid,
isnull(b.MembershipType, 0) as membershiptype,
count(isnull(a.affilID, 0)) as total
from @tblUsers a LEFT JOIN @tblTransactions b ON a.userID = b.userID
GROUP BY IsNull(a.affilID, 0), b.MembershipType) as tbla
group by affilid
order by affilid
EDIT:I must say I was confused by the date-requirements you had so I basicaly left them out...a clearer specification might be helpful.

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-16 : 19:02:12
Hi,
I also agree with Lumbago.
Mike i hope you got solution to your requirements.

Cheers
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-17 : 18:53:02
Hi Lumbargo, (and others :P)

Your solution works great and helps me out. There is a little bit of a problem with the date however, and I'm wondering if I should change the database design a touch.

I have the following data in my database

tbluserdetails

userID, affilID
500, 1
501, 1


tblmemberships

transactionID purchasedFor dateStart dateEnd membershipType

1 / 500 / 2002-01-01 / 2010-01-01 / 30


I run the following query:


select_AffiliateReports_All '01/01/2000', '01/01/2010'


and the results returned are the following

affilid / 10 / 20 / 30
1 / 0 / 0 / 1


I'm unable to follow exactly where its messing up, but when I take out

"WHERE m.DateStart > @dateStart AND m.dateStart < @dateEnd" it works fine.

Does this mean I will have to change my db structure and force all users with an affiliate ID to also have a record in tblMemberships? Or can I somehow create a default date without the record being there? Or even grab a date from a column in tbluserdetails ?

Here is the exact code below:


ALTER PROCEDURE dbo.select_AffiliateReports_All
(
@dateStart smalldatetime,
@dateEnd smalldatetime
)

AS SET NOCOUNT ON

select affilid,
sum(case when membershiptype = 0 then total else 0 end) as 10,
sum(case when membershiptype = 10 then total else 0 end) as 20,
sum(case when membershiptype = 20 then total else 0 end) as 30
from
(select isnull(ud.affilID, 0) as affilid,
isnull(m.MembershipType, 0) as membershiptype,
count(isnull(ud.affilID, 0)) as total
FROM tblUserDetails ud LEFT JOIN tblMemberShips m ON ud.userID = m.purchasedFor

--WHERE m.DateStart > @dateStart AND m.dateStart < @dateEnd

GROUP BY IsNull(ud.affilID, 0), m.MembershipType) as tbla
group by affilid
order by affilid


GO

thanks ALOT for the continued help on this problem, its been a real tough one for me and all of your help is making it come together!

thanks again!

mike123


Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-17 : 19:29:01
select_AffiliateReports_All '01/01/2000', '01/01/2010'
ALTER PROCEDURE dbo.select_AffiliateReport


First thing Procedure names are different.
Second you are passing two parameters to stored procedure instead of passing 3 parameters.

Cheers
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-17 : 19:39:47
quote:
Originally posted by mk_garg20

select_AffiliateReports_All '01/01/2000', '01/01/2010'
ALTER PROCEDURE dbo.select_AffiliateReport


First thing Procedure names are different.
Second you are passing two parameters to stored procedure instead of passing 3 parameters.

Cheers




Hi mk_garg20,

my apologies over that, I have posted the correct SP now :)

Thanks once again for your continued help!

mike123
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-17 : 20:08:29
quote:
Originally posted by mike123
affilid / 10 / 20 / 30
1 / 0 / 0 / 1



I think you have to update results as well.




Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-17 : 20:11:49
quote:
Originally posted by mk_garg20

quote:
Originally posted by mike123
affilid / 10 / 20 / 30
1 / 0 / 0 / 1



I think you have to update results as well.





Crap, this SPROC is really messin with my brain today. Results are the same, I just reposted the SPROC with proper names.

Thanks for your patience with me :)

Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-17 : 20:12:32
When you pass two dates to stored procedure, what do you want to check?

Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-08-17 : 20:18:43
tblmemberships

transactionID purchasedFor dateStart dateEnd membershipType

1 / 500 / 2002-01-01 / 2010-01-01 / 30


select affilid,
sum(case when membershiptype = 0 then total else 0 end) as 10,
sum(case when membershiptype = 10 then total else 0 end) as 20,
sum(case when membershiptype = 20 then total else 0 end) as 30

Mike your membership type in tblmemberships is "30"

what i can not see you are checking for membership type "30"in stored procedure


make sure it is not like this

sum(case when membershiptype = 10 then total else 0 end) as 10,
sum(case when membershiptype = 20 then total else 0 end) as 20,
sum(case when membershiptype = 30 then total else 0 end) as 30
Go to Top of Page

mike123
Master Smack Fu Yak Hacker

1462 Posts

Posted - 2004-08-17 : 21:02:02


Altho my brain is telling me I should give up and stop replying as Im making a mistake in each reply. I'm gonna try again.

This is the SPROC, it does in fact check for 30, I just modified it wrong. (I've switched a couple column names in reality, but am keeping the same ones in this thread as an attempt to not confuse, although it kinda backfired :P )

It seems to work fine but this line throws things off

"WHERE m.DateStart > @dateStart AND m.dateStart < @dateEnd"


Do you think I have to change my data structure to have a row in tblMemberShips for each member with an affilID not NULL.

Thanks again for your patience


ALTER PROCEDURE dbo.select_AffiliateReports_All
(
@dateStart smalldatetime,
@dateEnd smalldatetime
)

AS SET NOCOUNT ON

select affilid,
sum(case when membershiptype = 0 then total else 0 end) as 0,
sum(case when membershiptype = 10 then total else 0 end) as 10,
sum(case when membershiptype = 20 then total else 0 end) as 20,
sum(case when membershiptype = 30 then total else 0 end) as 30
from
(select isnull(ud.affilID, 0) as affilid,
isnull(m.MembershipType, 0) as membershiptype,
count(isnull(ud.affilID, 0)) as total
FROM tblUserDetails ud LEFT JOIN tblMemberShips m ON ud.userID = m.purchasedFor

WHERE m.DateStart > @dateStart AND m.dateStart < @dateEnd

GROUP BY IsNull(ud.affilID, 0), m.MembershipType) as tbla
group by affilid
order by affilid


GO
Go to Top of Page
    Next Page

- Advertisement -