Reputation: 15
I'm studying for an interview next week which has a small data analysis component. The recruiter gave me the following sample SQL question which I'm having trouble wrapping my mind around a solution. I'm hoping that I'm not biting off more than I can chew ;)..
SAMPLE QUESTION:
You are given two tables:
AdClick Table (columns: ClickID, AdvertiserID, UserID, and other fields) and AdConversion Table (columns: ClickID, UserID and other fields).
You have to find the total conversion rate (# of conversions/# of clicks) for users with 1 click, 2 click etc.
I've been playing with this for about an hour and keep hitting road blocks. I understand COUNT and GROUP BY but suspect I'm missing a simple SQL feature that I'm unaware of. This also makes it difficult for me to find any possible pointers/solutions via Google: not knowing the magic keywords to search on.
Example Input
dbo.AdConversion
----------------
ClickID UserID
1 1
2 1
4 1
5 3
6 2
7 2
12 1
9 4
10 4
dbo.AdClick
-----------
ClickID AdvertiserID UserID
1 1 1
2 2 1
3 1 2
4 1 1
5 1 3
6 2 2
7 3 2
8 1 1
9 4 4
10 2 4
11 3 4
12 2 1
Expected Result:
----------------
UserClickCount ConversionRate
4 80.00%
2 66.67%
1 100.00%
Explanation/Clarification:
Users with 4 AdConversion.ClickIDs (aka Conversions) have an 80% conversation rate. Here there's just one user, UserID 1, which has 5 AdClicks with 4 AdConversions.
Users with 2 Conversions have a combined 6 Adclicks with 4 conversions for a conversion rate of 66.67%. Here, that'd be UserID 2 and 4.
Users with 1 Conversion, here only UserID 3, has 1 conversion against 1 AdClick for a 100% conversion rate.
Here's one possible solution I've come up with after some direction from Zack's comment. I can't imagine that it's the ideal solution or whether it has bugs in it or not:
DECLARE @Conversions TABLE
(
UserID int NOT NULL,
AdConversions int
)
INSERT INTO @Conversions (UserID, AdConversions)
SELECT adc.UserID, COUNT(adc.UserID)
FROM dbo.AdConversion adc
GROUP BY adc.UserID;
DECLARE @Clicks TABLE
(
UserID int NOT NULL,
AdClicks int
)
INSERT INTO @Clicks(UserID, AdClicks)
SELECT UserID, Count (ClickID)
FROM dbo.AdClick
GROUP BY UserID;
SELECT co.AdConversions, CONVERT(decimal(6,3), (CAST(SUM(co.AdConversions) AS float) / SUM(cl.AdClicks))) * 100
FROM @Conversions co
INNER JOIN @Clicks cl
ON co.UserID = cl.UserID
GROUP BY co.AdConversions;
Any advice would be greatly appreciated!
Thanks, Michael
Upvotes: 1
Views: 2135
Reputation: 136
Your logic seems good. Here is a version with common table expressions and a little update with the numeric conversion:
WITH tConversions as
(SELECT UserID, COUNT(ClickID) as AdConversions
FROM AdConversion
GROUP BY UserID),
tClicks as
(SELECT UserID, COUNT(ClickID) as AdClicks
FROM AdClick
GROUP BY UserID)
SELECT co.AdConversions, CONVERT(decimal(10,2),CAST(SUM(co.AdConversions) as float) / SUM(cl.AdClicks) * 100) as ConversionRate
FROM tConversions co
INNER JOIN tClicks cl
ON co.UserID = cl.UserID
GROUP BY co.AdConversions
You can also use subqueries directly:
SELECT co.AdConversions, CONVERT(decimal(10,2),CAST(SUM(co.AdConversions) as float) / SUM(cl.AdClicks) * 100) as ConversionRate
FROM
(SELECT UserID, COUNT(ClickID) as AdConversions
FROM AdConversion
GROUP BY UserID)
as co
INNER JOIN
(SELECT UserID, COUNT(ClickID) as AdClicks
FROM AdClick
GROUP BY UserID)
as cl
ON co.UserID = cl.UserID
GROUP BY co.AdConversions
Upvotes: 2