Reputation: 938
I have a little problem. The data:
2016-11-09 0536B088-D3DE-4C0E-903F-C2463D0AAB7E 2016-11-09 866D70EC-93FD-4C30-BC54-C7B954F255BE 2016-11-09 6C090D6B-9842-4CB0-9E10-F9B941C8D3A1 2016-11-09 FB1DD63E-F098-4191-B8F4-BEA4F9776B54 2016-11-09 FB1DD63E-F098-4191-B8F4-BEA4F9776B54 2016-11-10 0536B088-D3DE-4C0E-903F-C2463D0AAB7E 2016-11-10 NULL 2016-11-10 0536B088-D3DE-4C0E-903F-C2463D0AAB7E 2016-11-11 0536B088-D3DE-4C0E-903F-C2463D0AAB7E 2016-11-11 0536B088-D3DE-4C0E-903F-C2463D0AAB7E
From it I want to count UserId and group via Date. I should be like this:
Date | Unique | Returning | New ..09 | 4 | 1 | 3 ..10 | 2 | 1 | 1 ..11 | 1 | 1 | 0
How I can do it? I have this query.
select
cast(EventTime as date) as 'Date',
count(distinct UserId) + count(distinct case when UserId is null then 1 end) as 'Unique users',
0 as 'Returning users',
0 as 'New users'
from
TelemetryData
where
DiscountId = '5F8851DD-DF77-46DC-885E-46ECA93F021C' and EventName = 'DiscountClick'
group by
cast(EventTime as date)`
Unique users = unique with NULL too!
Returing users = UserId who clicked more than 1 times isnull(sum(case when UserId(here shoudld be count) > 1 then 1 else 0 end), 1)
New users who clicked only one! isnull(sum(case when UserId(count also) = 1 then 1 else 0 end), 1)
@EDIT:
Ok, two of your results work perfect. But I need now integrate it with other query.
SELECT
'5F8851DD-DF77-46DC-885E-46ECA93F021C',
cast([dbo].[TelemetryData].[EventTime] as date) as 'Date',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountLike' then 1 else 0 end) as 'Likes',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountDislike' then 1 else 0 end) as 'Dis likes',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountSharing' then 1 else 0 end) as 'Shares',
SUM(case when [dbo].[TelemetryData].[EventName]='DiscountView' then 1 else 0 end) as 'Views',
SUM(case when [dbo].[TelemetryData].[EventName]='DiscountClick' then 1 else 0 end) as 'Clicks',
Sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountCode' then 1 else 0 end) as 'Downloaded codes',
Sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountSave' then 1 else 0 end) as 'Saves',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountClickWWW' then 1 else 0 end) as 'Page redirections',
Round(
cast(Sum(case when [dbo].[TelemetryData].[EventName]='DiscountClick' then 1 else 0 end) as float)
/
cast(
case when SUM(case when [dbo].[TelemetryData].[EventName]='DiscountView' then 1 else 0 end) = 0 then 1
else SUM(case when [dbo].[TelemetryData].[EventName]='DiscountView' then 1 else 0 end) end as float)
* 100, 2)
as 'Average CTR',
0 as 'Unique users',
0 as 'New users',
0 as 'Returning users',
Sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountCommentPositive' then 1 else 0 end) as 'Positive comments',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountCommentNegative' then 1 else 0 end) as 'Negative comments'
from [dbo].[TelemetryData]
where [dbo].[TelemetryData].[DiscountId] = '5F8851DD-DF77-46DC-885E-46ECA93F021C'
and ([dbo].[TelemetryData].[EventName] = 'DiscountView' or [dbo].[TelemetryData].[EventName] = 'DiscountClick' or
[dbo].[TelemetryData].[EventName] = 'DiscountDislike' or [dbo].[TelemetryData].[EventName] = 'DiscountCode' or
[dbo].[TelemetryData].[EventName] = 'DiscountLike' or [dbo].[TelemetryData].[EventName] = 'DiscountSharing' or
[dbo].[TelemetryData].[EventName] = 'DiscountClickWWW' or [dbo].[TelemetryData].[EventName] = 'DiscountSave' or
[dbo].[TelemetryData].[EventName] = 'DiscountCommentPositive' or [dbo].[TelemetryData].[EventName] = 'DiscountCommentNegative')
group by cast([dbo].[TelemetryData].[EventTime] as date)
order by cast([dbo].[TelemetryData].[EventTime] as date) asc
Now it will be hard...
Upvotes: 1
Views: 85
Reputation: 1178
The following query should work:
select EventTime,
max(DistinctRank) [Unique],
sum(CountOfDistinct - 1) Returning,
max(DistinctRank) - sum(CountOfDistinct - 1) New
from
(select distinct EventTime,
UserId,
rank() over (partition by EventTime order by UserId) DistinctRank,
count(1) over (partition by EventTime, UserId) CountOfDistinct
from TelemetryData) sub
group by EventTime
The subquery (run it separately and see for yourself) will return the unique combinations of EventTime and UserID, along with the the rank of each unique UserId for a given date, and the count of distinct values for each combination of EventTime and UserId:
EventDate UserId DistinctRank CountOfDistinct
2016-11-09 00:00:00.000 0536B088-D3DE-4C0E-903F-C2463D0AAB7E 1 1
2016-11-09 00:00:00.000 6C090D6B-9842-4CB0-9E10-F9B941C8D3A1 2 1
2016-11-09 00:00:00.000 866D70EC-93FD-4C30-BC54-C7B954F255BE 3 1
2016-11-09 00:00:00.000 FB1DD63E-F098-4191-B8F4-BEA4F9776B54 4 2
2016-11-10 00:00:00.000 NULL 1 1
2016-11-10 00:00:00.000 0536B088-D3DE-4C0E-903F-C2463D0AAB7E 2 2
2016-11-11 00:00:00.000 0536B088-D3DE-4C0E-903F-C2463D0AAB7E 1 2
Then the outer query gets the maximum DistinctRank for each unique pair, which is the number of unique UserIds for the EventDate, and essentially the sum of the subquery records where there were duplicates in UserId for a given EventDate, which is the number of returning users. The New column is just the difference between Unique and Returning. The result is:
Event Date Unique Returning New
2016-11-09 00:00:00.000 4 1 3
2016-11-10 00:00:00.000 2 1 1
2016-11-11 00:00:00.000 1 1 0
Upvotes: 0
Reputation: 94894
You want aggregated user information in your results. One obvious and simple solution is to group by date and user first so as to get this information per user and date and only later group by date only.
select
eventdate,
count(*) as unique_users,
count(case when cnt > 1 then 1 end) as returning_users,
count(case when cnt = 1 then 1 end) as new_users
from
(
select cast(eventtime as date) as eventdate, userid, count(*) as cnt
from telemetrydata
where ...
group by cast(eventtime as date), userid
) date_user
group by eventdate;
Upvotes: 1
Reputation: 2774
Try below query
select Date, uniques, returning, uniques-returning as new
from (
select Date,
sum(case when row_num = 1 then 1 else 0 end) uniques,
sum(case when row_num = 2 then 1 else 0 end) returning
from(
select cast(EventTime as date) as Date,
ROW_NUMBER() over(partition by EventTime, userid order by EventTime) row_num
from TelemetryData) cte1
group by Date)cte2
Hope this should help you
Upvotes: 0
Reputation: 7753
Try this using a Common Table Expression:
Setup
CREATE TABLE #TelemetryData
(
EventTime Date,
UserId UNIQUEIDENTIFIER NULL
)
INSERT INTO #TelemetryData
VALUES
('2016-11-09', '0536B088-D3DE-4C0E-903F-C2463D0AAB7E'),
('2016-11-09', '866D70EC-93FD-4C30-BC54-C7B954F255BE'),
('2016-11-09', '6C090D6B-9842-4CB0-9E10-F9B941C8D3A1'),
('2016-11-09', 'FB1DD63E-F098-4191-B8F4-BEA4F9776B54'),
('2016-11-09', 'FB1DD63E-F098-4191-B8F4-BEA4F9776B54'),
('2016-11-10', '0536B088-D3DE-4C0E-903F-C2463D0AAB7E'),
('2016-11-10', NULL),
('2016-11-10', '0536B088-D3DE-4C0E-903F-C2463D0AAB7E'),
('2016-11-11', '0536B088-D3DE-4C0E-903F-C2463D0AAB7E'),
('2016-11-11', '0536B088-D3DE-4C0E-903F-C2463D0AAB7E')
Query
;WITH CTE
AS
(
SELECT EventTime,
UserId,
COUNT(*) cnt,
ROW_NUMBER() OVER (PARTITION BY EventTime ORDER BY EventTime) RN
FROM #TelemetryData
GROUP BY EventTime, UserId
)
SELECT EventTime,
MAX(RN) AS [Unique],
SUM(CASE WHEN cnt > 1 THEN 1 ELSE 0 END) as New,
SUM(CASE WHEN cnt = 1 THEN 1 ELSE 0 END) AS Returning
FROM CTE
GROUP BY EventTime
Results
EventTime Unique New Returning
2016-11-09 4 1 3
2016-11-10 2 1 1
2016-11-11 1 1 0
Upvotes: 0
Reputation: 133360
Could be i don't understand you question but looking to your data seems that you need
select
date
, count(*) as unique
, (count(*) - count(distinct user_id)) as returning
, count(distinct user_id) as new
group by date
were user_id is not null
Upvotes: 0