Sent, Unsubscribes, Opens, and Clicks in Past Month
I. Data Views
SFMC Dataviews required for this query include:
_Job
_Sent
_Unsubscribe
_Open
_Click
II. Methodology
Querying this many dataviews within SFMC within one SQL query is a bad idea; due to the 30-minute timeout rule, you’ll probably run into issues. It’s recommended to break this up into parts for each portion:
1) JobID Driver Query/DE -- Header includes a) jobid, b) email metadata
2 - 5) Sent/Unsub/Open/Click Stage Query/DE -- Header includes a) jobid and b) associated counts
6) Production Query/DE -- Header includes a) jobid, b) email metadata, and c) associated counts
NOTE: jobid + batchid + subscriberid acts as a unique identifier for a send within these dataviews.
III. Query: Driver
The results from this _job query will “drive” all of the other queries, act as the backbone of the report. We need to grab the email metadata within the time frame we need.
III-A. Previous Month Logic
In MS SQL Server, we need to use DATEPART(m, DATEADD(m, -1, GETDATE()))
to get the previous month.
III-B. Previous Month's Year Logic
We also need to ensure the year is aligned. Although these dataviews will only go back 6 months, we still want to be diligent to write reusable SQL that is accurate and definite. If we could go beyond 6 months, if the previous month in a query was July, our query would get all July data regardless of year. We need DATEPART(yyyy, DATEADD(m, -1, GETDATE()))
.
III-C. SQL Query
SELECT
a.jobid
,a.emailname
,a.emailsubject
,a.schedtime
FROM _job a
WHERE DATEPART(m, a.schedtime) = DATEPART(m, DATEADD(m, -1, GETDATE()))
AND DATEPART(yyyy, a.schedtime) = DATEPART(yyyy, DATEADD(m, -1, GETDATE()))
IV. Query: Stages
The stages are pretty concise and simple, but each of these stages need to be individual query objects to avoid timeouts.
IV-A. SQL Query: Stage Sent
This might be the only staging query that uses a particular combination of counting the jobid/batchid/subscriberid. This is up to the user and based on what the user is looking for, but if we want to see each individual send per jobid, we’ll want to include the batchid AND subscriberid (in SQL example below). If we want to see each user sent to per each jobid, we would just need subscriberid.
SELECT
a.jobid
,COUNT(a.batchid + a.subscriberid) AS sent
FROM _sent a
INNER JOIN driver_jobid_DE b
ON a.jobid = b.jobid
GROUP BY
a.jobid
IV-B. SQL Query: Stage Unsubs/Opens/Clicks
Again, how we count here depends on the user needs. In this example, we’ll just grab user count per jobid.
SELECT
a.jobid
,COUNT(a.subscriberid) AS stage_count_col /* useful identifier here, like 'unsubs'/'opens'/'clicks' */
FROM associated_dataview a
INNER JOIN jobid_driver_DE b
ON a.jobid = b.jobid
GROUP BY
a.jobid
V. Query: Production Report
Time to join everything together into one table. The "sent" and "jobid" DEs will act as our backbone. We'll use ISNULL() logic to ensure NULL values become zeroes.
SELECT
b.jobid
,b.emailname
,b.emailsubject
,b.schedtime
,ISNULL(a.sent, '0') AS sent
,ISNULL(c.unsubs, '0') AS unsubs
,ISNULL(d.opens, '0') AS opens
,ISNULL(e.clicks, '0') AS clicks
FROM stage_sent_DE a
INNER JOIN driver_jobid_DE b
ON a.jobid = b.jobid
LEFT JOIN stage_unsubs_DE c
ON a.jobid = c.jobid
LEFT JOIN stage_opens_DE d
ON a.jobid = d.jobid
LEFT JOIN stage_clicks_DE e
ON a.jobid = e.jobid
Happy Marketing Clouding!