Articles in this section

Setup Guide: Activtrak for Google Data Studio - Financial Loss

The Financial Loss template provides leaders with clear visibility into suspicious work patterns that may indicate the use of work-mimicking technology. This specialized analytics tool helps you quickly identify unusual activity signals, quantify potential productivity impacts, and take informed action. Detecting and addressing potential false activity can ensure your workforce data accurately reflects genuine productivity.

ActivConnect is available as an add-on for customers on a paid plan. Learn more about ActivConnect here.

Contents

Template access requirements

Before you begin, ensure you have:

  • An ActivTrak paid plan and the ActivConnect API (Add-on)
  • Your ActivConnect username ([account_number]@activtrak.us) and password. Your account number is in the Account Information menu in ActivTrak; access it via the circle icon in the top right corner.

Access the template

Validate ActivConnect credentials

  1. Navigate to Google Cloud Console
  2. Log in with your ActivConnect username ([account_number]@activtrak.us) and password

Take template ownership

To protect your data, ActivConnect restricts data sharing outside the activtrak.us domain. The steps outlined in this section will guide you through setting up permissions to grant data access to anyone within your organization.

  1. Navigate to https://lookerstudio.google.com and ensure you are logged in under your company’s Google account
  2. Starting from ActivTrak for Financial Loss (available here), make a copy of the report to take ownership of it and enable configuration and editing functions

 

  1. Keep the data sources on the prompt and click Copy Report to continue

 

  1. Click the Share button in the upper right corner and provide Editor permissions to your ActivConnect user account. This will be in the format of [account_number]@activtrak.us.

Set up data sources

  1. In a separate tab or incognito window, ensure you are logged in with your ActivConnect user account. This will be in the format of ([account_number]@activtrak.us). Your account number is in the Account Information menu in ActivTrak; access it via the circle icon in the top right corner.
  2. Then, navigate to https://lookerstudio.google.com
  3. Select the Shared with Me tab from the left navigation menu and open your copy of ActivTrak for Data Studio - Financial Loss
  4. Enter Edit Mode by clicking the blue Edit button in the top right corner

Performance by Group

  1. Click Resource > Manage added data sources

 

  1. Click on Edit to the right of Performance by Group

  2. Click on Edit Connection at the top

 

  1. Change the highlighted “AC_Demo” into your 6-digit account number. There are 3 AC_Demo placeholders to replace.  

     

  2. The default date parameter is set to 2024-12-01. Update this if needed. The parameter must be in the YYYY-MM-DD format. This script has only one date parameter.
  1. Click on Reconnect at the top right

 

  1. Click Apply in the pop-up window to confirm the changes. Then click Done once complete. 
Click to view code
WITH group_goals AS (
  SELECT 
    account_id, 
    user_id, 
    is_primary_group, 
    group_id, 
    group_name, 
    user_name,
    productive_hrs_day as group_productive_hrs_goal,
    focused_hrs_day as group_focused_hrs_goal,
    collaboration_hrs_day as group_collaboration_hrs_goal
  FROM (
    SELECT 
      pug.account_id, 
      pug.user_id, 
      pug.is_primary_group, 
      pug.group_id, 
      pug.group_name, 
      pug.user_name, 
      gg.metric_name, 
      gg.target_value
    FROM `us-activtrak-ac-prod.AC_Demo.premium_user_groups` pug
    INNER JOIN `us-activtrak-ac-prod.AC_Demo.group_goals` gg 
      ON gg.group_id = pug.group_id
  )
  PIVOT (
    MAX(target_value) 
    FOR metric_name IN (
      'productive_hrs_day',
      'focused_hrs_day', 
      'collaboration_hrs_day'
    )
  )
), 

daily_metrics as (
  SELECT *,
    CONCAT(local_date, "_", user_name) as date_user,
    DATE_TRUNC(local_date, MONTH) as date_month,
    CASE 
      WHEN SUM(active_day_count) IS NULL THEN
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / COUNT(DISTINCT CONCAT(local_date, "_", user_name))
      WHEN SUM(active_day_count) = 0 THEN
        NULL
      ELSE
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / SUM(active_day_count)
    END AS productive_hrs_day
  FROM `us-activtrak-ac-prod.AC_Demo.daily_user_summary`
  GROUP BY ALL
),

base_data AS (
  SELECT gg.*, dm.* EXCEPT (user_id, user_name)
  FROM group_goals gg
  INNER JOIN daily_metrics dm ON dm.user_id = gg.user_id
  WHERE local_date = '2024-12-01'
),

user_monthly_averages AS (
  SELECT 
    group_id,
    group_name,
    user_id,
    user_name,
    is_primary_group,
    group_productive_hrs_goal,
    date_month,
    FORMAT_DATE('%Y-%m', date_month) as monthyear,
    AVG(productive_hrs_day) as avg_productive_hrs_day
  FROM base_data
  WHERE productive_hrs_day IS NOT NULL
  GROUP BY 
    group_id, 
    group_name, 
    user_id, 
    user_name, 
    is_primary_group, 
    group_productive_hrs_goal, 
    date_month
)

SELECT 
  monthyear,
  group_name,
 COUNT(CASE WHEN is_primary_group = true THEN user_id END) as count_of_users,
  COUNT(CASE WHEN is_primary_group = true AND avg_productive_hrs_day < group_productive_hrs_goal THEN user_id END) as users_below_goal,
  COUNT(CASE WHEN is_primary_group = true AND avg_productive_hrs_day < 5 THEN user_id END) as users_below_5_productive_hrs,
  SUM(CASE 
      WHEN avg_productive_hrs_day is not null AND avg_productive_hrs_day <= group_productive_hrs_goal
      THEN (group_productive_hrs_goal - avg_productive_hrs_day) / group_productive_hrs_goal 
    END) AS unused_capacity
FROM user_monthly_averages
GROUP BY monthyear, group_name
ORDER BY monthyear DESC, group_name
;

Performance by Location

Repeat the same steps as the Performance by Group data set up, but pick the Performance by Location data source this time. There are 5 AC_Demo placeholders to replace. The default date parameter is set to 2024-12-01. Update this if needed. This script has two date parameters.

Click to view code
  WITH group_goals AS (
  SELECT 
    account_id, 
    user_id, 
    is_primary_group, 
    group_id, 
    group_name, 
    user_name,
    productive_hrs_day as group_productive_hrs_goal,
    focused_hrs_day as group_focused_hrs_goal,
    collaboration_hrs_day as group_collaboration_hrs_goal
  FROM (
    SELECT 
      pug.account_id, 
      pug.user_id, 
      pug.is_primary_group, 
      pug.group_id, 
      pug.group_name, 
      pug.user_name, 
      gg.metric_name, 
      gg.target_value
    FROM (
      SELECT * FROM `us-activtrak-ac-prod.AC_Demo.premium_user_groups`
      WHERE is_primary_group = true 
      QUALIFY ROW_NUMBER() OVER (PARTITION BY user_name ORDER BY user_id DESC) = 1
    ) pug
    INNER JOIN `us-activtrak-ac-prod.AC_Demo.group_goals` gg 
      ON gg.group_id = pug.group_id
  )
  PIVOT (
    MAX(target_value) 
    FOR metric_name IN (
      'productive_hrs_day',
      'focused_hrs_day', 
      'collaboration_hrs_day'
    )
  )
), 

daily_metrics AS (
  SELECT 
    user_name,
    local_date,
    DATE_TRUNC(local_date, MONTH) as date_month,
    CONCAT(local_date, "_", user_name) as date_user,
    CASE 
      WHEN SUM(active_day_count) IS NULL THEN
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / COUNT(*)
      WHEN SUM(active_day_count) = 0 THEN
        NULL
      ELSE
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / SUM(active_day_count)
    END AS productive_hrs_day
  FROM `us-activtrak-ac-prod.AC_Demo.daily_user_summary`
  WHERE local_date = '2024-12-01'
  GROUP BY user_name, local_date
),

user_work_location_labels AS (
  SELECT 
    user_name,
    DATE_TRUNC(local_date, MONTH) as date_month,
    FORMAT_DATE('%Y-%m', DATE_TRUNC(local_date, MONTH)) as monthyear,
    ARRAY_AGG(DISTINCT location IGNORE NULLS) as locations_used,
    CASE 
      WHEN 
        COUNT(DISTINCT CASE WHEN location = 'Office' THEN location END)  0
        AND COUNT(DISTINCT CASE WHEN location IN ('Remote', 'Office/Remote', 'Unknown') THEN location END) = 0
      THEN 'Office Only'
      WHEN 
        COUNT(DISTINCT CASE WHEN location = 'Remote' THEN location END)  0
        AND COUNT(DISTINCT CASE WHEN location IN ('Office', 'Office/Remote', 'Unknown') THEN location END) = 0
      THEN 'Remote Only'
      ELSE 'Hybrid'
    END AS user_work_location_label
  FROM `us-activtrak-ac-prod.AC_Demo.daily_user_summary`
  WHERE local_date >= '2024-12-01'
    AND location IS NOT NULL 
    AND TRIM(location) != ''
  GROUP BY user_name, DATE_TRUNC(local_date, MONTH), FORMAT_DATE('%Y-%m', DATE_TRUNC(local_date, MONTH))
),

base_data AS (
  SELECT gg.*, dm.* EXCEPT (user_name)
  FROM group_goals gg
  INNER JOIN daily_metrics dm ON dm.user_name = gg.user_name
),

user_monthly_productivity AS (
  SELECT 
    user_name,
    user_id,
    group_name,
    group_id,
    is_primary_group,
    group_productive_hrs_goal,
    date_month,
    FORMAT_DATE('%Y-%m', date_month) as monthyear,
    AVG(productive_hrs_day) as avg_productive_hrs_day
  FROM base_data
  WHERE productive_hrs_day IS NOT NULL
  GROUP BY 
    user_name, 
    user_id, 
    group_name, 
    group_id,
    is_primary_group, 
    group_productive_hrs_goal, 
    date_month
),

user_performance_with_location AS (
  SELECT 
    ump.user_name,
    ump.user_id,
    ump.group_name,
    ump.group_id,
    ump.is_primary_group,
    ump.group_productive_hrs_goal,
    ump.date_month,
    ump.monthyear,
    ump.avg_productive_hrs_day,
    COALESCE(wl.user_work_location_label, 'Unknown') as user_work_location_label,
    wl.locations_used,
    CASE 
      WHEN ump.avg_productive_hrs_day IS NULL THEN NULL
      WHEN ump.avg_productive_hrs_day >= ump.group_productive_hrs_goal THEN 0
      ELSE (ump.group_productive_hrs_goal - ump.avg_productive_hrs_day) / ump.group_productive_hrs_goal
    END AS unused_capacity_fte
  FROM user_monthly_productivity ump
  LEFT JOIN user_work_location_labels wl 
    ON ump.user_name = wl.user_name
    AND ump.date_month = wl.date_month
),

work_location_metrics AS (
  SELECT 
    monthyear,
    group_name,
    user_work_location_label,
    COUNT(DISTINCT CASE 
      WHEN avg_productive_hrs_day IS NOT NULL 
           AND avg_productive_hrs_day < group_productive_hrs_goal 
           AND is_primary_group = true
      THEN user_name 
    END) as user_count_below_goal_by_location,
    COUNT(DISTINCT CASE 
      WHEN avg_productive_hrs_day IS NOT NULL 
           AND is_primary_group = true
      THEN user_name 
    END) as total_users_by_location,
    SUM(CASE 
      WHEN unused_capacity_fte IS NOT NULL 
           AND unused_capacity_fte > 0 
           AND is_primary_group = true
      THEN unused_capacity_fte 
      ELSE 0 
    END) as unused_capacity_fte_by_location
  FROM user_performance_with_location
  WHERE user_work_location_label IN ('Hybrid', 'Office Only', 'Remote Only', 'Unknown')
  GROUP BY monthyear, group_name, user_work_location_label
)

SELECT 
  monthyear,
  group_name,
  user_work_location_label,
  total_users_by_location,
  user_count_below_goal_by_location,
  unused_capacity_fte_by_location
FROM work_location_metrics
WHERE total_users_by_location > 0
ORDER BY monthyear DESC, group_name, user_work_location_label
;

Performance by Productivity Threshold

Repeat the same steps as the Performance by Group data set up, but pick the Performance by Productivity Threshold data source this time. There are 3 AC_Demo placeholders to replace. The default date parameter is set to 2024-12-01. Update this if needed. This script has only one date parameter.

Click to view code
  WITH group_goals AS (
  SELECT 
    account_id, 
    user_id, 
    is_primary_group, 
    group_id, 
    group_name, 
    user_name,
    productive_hrs_day as group_productive_hrs_goal,
    focused_hrs_day as group_focused_hrs_goal,
    collaboration_hrs_day as group_collaboration_hrs_goal
  FROM (
    SELECT 
      pug.account_id, 
      pug.user_id, 
      pug.is_primary_group, 
      pug.group_id, 
      pug.group_name, 
      pug.user_name, 
      gg.metric_name, 
      gg.target_value
    FROM (
      SELECT * FROM `us-activtrak-ac-prod.AC_Demo.premium_user_groups`
      WHERE is_primary_group = true 
      QUALIFY ROW_NUMBER() OVER (PARTITION BY user_name ORDER BY user_id DESC) = 1
    ) pug
    INNER JOIN `us-activtrak-ac-prod.AC_Demo.group_goals` gg 
      ON gg.group_id = pug.group_id
  )
  PIVOT (
    MAX(target_value) 
    FOR metric_name IN (
      'productive_hrs_day',
      'focused_hrs_day', 
      'collaboration_hrs_day'
    )
  )
), 

daily_metrics AS (
  SELECT 
    user_name,
    local_date,
    DATE_TRUNC(local_date, MONTH) as date_month,
    CONCAT(local_date, "_", user_name) as date_user,
    CASE 
      WHEN SUM(active_day_count) IS NULL THEN
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / COUNT(*)
      WHEN SUM(active_day_count) = 0 THEN
        NULL
      ELSE
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / SUM(active_day_count)
    END AS productive_hrs_day
  FROM `us-activtrak-ac-prod.AC_Demo.daily_user_summary`
  WHERE local_date >= '2024-12-01'
  GROUP BY user_name, local_date
),

productive_hrs_cutoff AS (
  SELECT productive_hrs_cutoff 
  FROM UNNEST(GENERATE_ARRAY(1, 8, 1)) AS productive_hrs_cutoff
),

base_data AS (
  SELECT gg.*, dm.* EXCEPT (user_name)
  FROM group_goals gg
  INNER JOIN daily_metrics dm ON dm.user_name = gg.user_name
),

user_monthly_productivity AS (
  SELECT 
    user_name,
    user_id,
    group_name,
    group_id,
    is_primary_group,
    group_productive_hrs_goal,
    date_month,
    FORMAT_DATE('%Y-%m', date_month) as monthyear,
    AVG(productive_hrs_day) as avg_productive_hrs_day
  FROM base_data
  WHERE productive_hrs_day IS NOT NULL
  GROUP BY 
    user_name, 
    user_id, 
    group_name, 
    group_id,
    is_primary_group, 
    group_productive_hrs_goal, 
    date_month
),

monthly_cutoff_combinations AS (
  SELECT 
    ump.monthyear,
    ump.date_month,
    phc.productive_hrs_cutoff,
    ump.user_name,
    ump.user_id,
    ump.group_name,
    ump.is_primary_group,
    ump.group_productive_hrs_goal,
    ump.avg_productive_hrs_day,
    CASE 
      WHEN ump.avg_productive_hrs_day IS NULL THEN 0
      WHEN ump.avg_productive_hrs_day >= phc.productive_hrs_cutoff THEN 0 
      WHEN ump.avg_productive_hrs_day >= ump.group_productive_hrs_goal THEN 0
      ELSE (ump.group_productive_hrs_goal - ump.avg_productive_hrs_day) / ump.group_productive_hrs_goal
    END AS unused_capacity_fte
  FROM user_monthly_productivity ump
  CROSS JOIN productive_hrs_cutoff phc
),

monthly_totals AS (
  SELECT 
    monthyear,
    group_name,
    COUNT(DISTINCT CASE 
      WHEN is_primary_group = true 
      THEN user_name 
    END) as total_user_count
  FROM user_monthly_productivity
  GROUP BY monthyear, group_name
),

monthly_totals_all_groups AS (
  SELECT 
    monthyear,
    COUNT(DISTINCT CASE 
      WHEN is_primary_group = true 
      THEN user_name 
    END) as total_user_count_all_groups
  FROM user_monthly_productivity
  GROUP BY monthyear
),

productivity_threshold_metrics AS (
  SELECT 
    mcc.monthyear,
    mcc.group_name,
    mcc.productive_hrs_cutoff,
    CONCAT('< ', CAST(mcc.productive_hrs_cutoff AS STRING), ' Hrs/Day') as x_axis_value,
    COUNT(DISTINCT CASE 
      WHEN mcc.avg_productive_hrs_day < mcc.productive_hrs_cutoff 
           AND mcc.is_primary_group = true
      THEN mcc.user_name 
    END) as user_count_below_x_productive_hours,
    SUM(CASE 
      WHEN mcc.avg_productive_hrs_day < mcc.productive_hrs_cutoff 
           AND mcc.unused_capacity_fte > 0 
           AND mcc.is_primary_group = true
      THEN mcc.unused_capacity_fte 
      ELSE 0 
    END) as unused_capacity_fte_below_x_productive_hrs
  FROM monthly_cutoff_combinations mcc
  GROUP BY mcc.monthyear, mcc.group_name, mcc.productive_hrs_cutoff
),

productivity_threshold_summary AS (
  SELECT 
    ptm.*,
    mt.total_user_count,
    mtag.total_user_count_all_groups,
  FROM productivity_threshold_metrics ptm
  LEFT JOIN monthly_totals mt 
    ON ptm.monthyear = mt.monthyear 
    AND ptm.group_name = mt.group_name
  LEFT JOIN monthly_totals_all_groups mtag 
    ON ptm.monthyear = mtag.monthyear
)

SELECT 
  monthyear,
  group_name,
  productive_hrs_cutoff,
  x_axis_value,
  total_user_count,
  total_user_count_all_groups,
  user_count_below_x_productive_hours,
  unused_capacity_fte_below_x_productive_hrs
FROM productivity_threshold_summary
ORDER BY monthyear DESC, group_name, productive_hrs_cutoff
;

Recurring Low Utilization

Repeat the same steps as the Performance by Group data set up, but pick the Recurring Low Utilization data source this time. There are 3 AC_Demo placeholders to replace. The default date parameter is set to 2024-12-01. Update this if needed. This script has only one date parameter.

Click to view code
WITH consecutive_months_buckets AS (
  SELECT months_below_goal, lower_bound, upper_bound FROM UNNEST([
    STRUCT('< 2 Months' AS months_below_goal, 0 AS lower_bound, 1 AS upper_bound),
    STRUCT('2 - 4 Months' AS months_below_goal, 2 AS lower_bound, 4 AS upper_bound),
    STRUCT('5 - 8 Months' AS months_below_goal, 5 AS lower_bound, 8 AS upper_bound),
    STRUCT('> 8 Months' AS months_below_goal, 9 AS lower_bound, 999999999 AS upper_bound)
  ])
),


group_goals AS (
  SELECT 
    account_id, 
    user_id, 
    is_primary_group, 
    group_id, 
    group_name, 
    user_name,
    productive_hrs_day as group_productive_hrs_goal,
    focused_hrs_day as group_focused_hrs_goal,
    collaboration_hrs_day as group_collaboration_hrs_goal
  FROM (
    SELECT 
      pug.account_id, 
      pug.user_id, 
      pug.is_primary_group, 
      pug.group_id, 
      pug.group_name, 
      pug.user_name, 
      gg.metric_name, 
      gg.target_value
    FROM (
      SELECT * FROM `us-activtrak-ac-prod.AC_Demo.premium_user_groups`
      WHERE is_primary_group = true 
      QUALIFY ROW_NUMBER() OVER (PARTITION BY user_name ORDER BY user_id DESC) = 1
    ) pug
    INNER JOIN `us-activtrak-ac-prod.AC_Demo.group_goals` gg 
      ON gg.group_id = pug.group_id
  )
  PIVOT (
    MAX(target_value) 
    FOR metric_name IN (
      'productive_hrs_day',
      'focused_hrs_day', 
      'collaboration_hrs_day'
    )
  )
), 

daily_metrics AS (
  SELECT 
    user_name,
    local_date,
    DATE_TRUNC(local_date, MONTH) as date_month,
    CONCAT(local_date, "_", user_name) as date_user,
    CASE 
      WHEN SUM(active_day_count) IS NULL THEN
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / COUNT(*)
      WHEN SUM(active_day_count) = 0 THEN
        NULL
      ELSE
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / SUM(active_day_count)
    END AS productive_hrs_day
  FROM `us-activtrak-ac-prod.AC_Demo.daily_user_summary`
  WHERE local_date = '2024-01-01'
  GROUP BY user_name, local_date 
),

base_data AS (
  SELECT gg.*, dm.* EXCEPT (user_name)
  FROM group_goals gg
  INNER JOIN daily_metrics dm ON dm.user_name = gg.user_name
),

user_monthly_averages AS (
  SELECT 
    group_id, group_name, user_id, user_name, is_primary_group,
    group_productive_hrs_goal, date_month,
    FORMAT_DATE('%Y-%m', date_month) as monthyear,
    AVG(productive_hrs_day) as avg_productive_hrs_day,
    CASE 
      WHEN AVG(productive_hrs_day) < group_productive_hrs_goal THEN 1 
      ELSE 0 
    END as is_below_goal,
    CASE 
      WHEN AVG(productive_hrs_day) IS NOT NULL 
           AND AVG(productive_hrs_day) < group_productive_hrs_goal 
      THEN (group_productive_hrs_goal - AVG(productive_hrs_day)) / group_productive_hrs_goal
      ELSE 0
    END as unused_capacity_fte
  FROM base_data
  WHERE productive_hrs_day IS NOT NULL
  GROUP BY 
    group_id, group_name, user_id, user_name, is_primary_group, 
    group_productive_hrs_goal, date_month
),
user_streak_groups AS (
  SELECT 
    *,
    SUM(CASE WHEN is_below_goal = 0 THEN 1 ELSE 0 END) 
      OVER (PARTITION BY user_name ORDER BY date_month) as streak_break_group
  FROM user_monthly_averages
),

user_consecutive_months AS (
  SELECT 
    monthyear,
    date_month,
    group_id,
    group_name,
    user_id,
    user_name,
    is_primary_group,
    group_productive_hrs_goal,
    avg_productive_hrs_day,
    is_below_goal,
    unused_capacity_fte,
    streak_break_group,
    CASE 
      WHEN is_below_goal = 1 THEN
        ROW_NUMBER() OVER (
          PARTITION BY user_name, streak_break_group, is_below_goal
          ORDER BY date_month
        )
      ELSE 0
    END as consecutive_months_below_goal
  FROM user_streak_groups
  QUALIFY ROW_NUMBER() OVER (PARTITION BY user_name, date_month ORDER BY group_id) = 1
),

user_monthly_status AS (
  SELECT 
    monthyear,
    date_month,
    group_id,
    group_name,
    user_id,
    user_name,
    is_primary_group,
    group_productive_hrs_goal,
    avg_productive_hrs_day,
    is_below_goal,
    unused_capacity_fte,
    consecutive_months_below_goal,
    MAX(consecutive_months_below_goal) 
      OVER (PARTITION BY user_name, streak_break_group ORDER BY date_month) as current_streak_length
  FROM user_consecutive_months
),

users_in_buckets AS (
  SELECT 
    ums.monthyear,
    ums.date_month,
    ums.group_name,
    ums.user_name,
    ums.is_primary_group,
    ums.is_below_goal,
    ums.consecutive_months_below_goal,
    ums.unused_capacity_fte,
    cmb.months_below_goal as bucket_label
  FROM user_monthly_status ums
  CROSS JOIN consecutive_months_buckets cmb
  WHERE ums.is_below_goal = 1 
    AND ums.consecutive_months_below_goal >= cmb.lower_bound 
    AND ums.consecutive_months_below_goal <= cmb.upper_bound
),

monthly_totals AS (
  SELECT 
    monthyear,
    COUNT(DISTINCT CASE WHEN is_primary_group = true THEN user_name END) as total_users_all_groups
  FROM user_monthly_status
  GROUP BY monthyear
),

aggregated_results AS (
  SELECT 
    uib.monthyear,
    uib.date_month,
    uib.group_name,
    uib.bucket_label as months_below_goal,
    COUNT(DISTINCT CASE 
      WHEN uib.is_primary_group = true 
      THEN uib.user_name 
    END) as recurring_users,
    SUM(CASE 
      WHEN uib.is_primary_group = true 
      THEN uib.unused_capacity_fte 
      ELSE 0 
    END) as unused_capacity_fte,
    MAX(mt.total_users_all_groups) as total_users
  FROM users_in_buckets uib
  LEFT JOIN monthly_totals mt ON uib.monthyear = mt.monthyear
  GROUP BY 
    uib.monthyear,
    uib.date_month,
    uib.group_name,
    uib.bucket_label
)

SELECT 
  monthyear,
  date_month,
  group_name,
  months_below_goal,
  recurring_users,
  total_users,
  unused_capacity_fte
FROM aggregated_results
UNION ALL
SELECT 
  monthyear,
  date_month,
  group_name,
  months_below_goal,
  0 as recurring_users,
  total_users,
  0 as unused_capacity_fte
FROM (
  SELECT DISTINCT 
    ums.monthyear,
    ums.date_month,
    ums.group_name,
    cmb.months_below_goal,
    mt.total_users_all_groups as total_users
  FROM user_monthly_status ums
  CROSS JOIN consecutive_months_buckets cmb
  LEFT JOIN monthly_totals mt ON ums.monthyear = mt.monthyear
)
WHERE (monthyear, group_name, months_below_goal) NOT IN (
  SELECT (monthyear, group_name, months_below_goal) 
  FROM aggregated_results
)
ORDER BY 
  date_month DESC,
  group_name,
  CASE months_below_goal
    WHEN '< 2 Months' THEN 1
    WHEN '2 - 4 Months' THEN 2
    WHEN '5 - 8 Months' THEN 3
    WHEN '> 8 Months' THEN 4
  END
;

6-Month Productivity Trend

Repeat the same steps as the Performance by Group data set up, but pick the 6-Month Productivity Trend data source this time. There are 4 AC_Demo placeholders to replace. There are no date parameters in this script.

Click to view code
WITH latest_complete_month AS (
  SELECT 
    MAX(DATE_TRUNC(local_date, MONTH)) as last_month
  FROM `us-activtrak-ac-prod.AC_Demo.daily_user_summary`
  WHERE DATE_TRUNC(local_date, MONTH) < DATE_TRUNC(CURRENT_DATE(), MONTH)
),

six_month_range AS (
  SELECT 
    last_month as end_month,
    DATE_SUB(last_month, INTERVAL 5 MONTH) as start_month
  FROM latest_complete_month
),

trend_months AS (
  SELECT 
    FORMAT_DATE('%Y-%m', DATE_ADD(smr.start_month, INTERVAL offset MONTH)) as monthyear,
    DATE_ADD(smr.start_month, INTERVAL offset MONTH) as trend_date,
    offset + 1 as month_order
  FROM six_month_range smr
  CROSS JOIN UNNEST(GENERATE_ARRAY(0, 5)) as offset
),

group_goals AS (
  SELECT 
    user_name, 
    group_name, 
    is_primary_group,
    productive_hrs_day as group_productive_hrs_goal
  FROM (
    SELECT 
      pug.user_name, 
      pug.group_name, 
      pug.is_primary_group,
      gg.metric_name, 
      gg.target_value
    FROM (
      SELECT * FROM `us-activtrak-ac-prod.AC_Demo.premium_user_groups`
      WHERE is_primary_group = true 
      QUALIFY ROW_NUMBER() OVER (PARTITION BY user_name ORDER BY user_id DESC) = 1
    ) pug
    INNER JOIN `us-activtrak-ac-prod.AC_Demo.group_goals` gg 
      ON gg.group_id = pug.group_id
  )
  PIVOT (MAX(target_value) FOR metric_name IN ('productive_hrs_day'))
),

daily_metrics AS (
  SELECT 
    user_name,
    local_date,
    DATE_TRUNC(local_date, MONTH) as date_month,
    CONCAT(local_date, "_", user_name) as date_user,
    CASE 
      WHEN SUM(active_day_count) IS NULL THEN
        (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / COUNT(*)
      WHEN SUM(active_day_count) = 0 THEN NULL
      ELSE (SUM(productive_active_duration_seconds) + SUM(productive_passive_duration_seconds)) / 3600 / SUM(active_day_count)
    END AS productive_hrs_day
  FROM `us-activtrak-ac-prod.AC_Demo.daily_user_summary`
  CROSS JOIN six_month_range smr
  WHERE DATE_TRUNC(local_date, MONTH) >= smr.start_month
    AND DATE_TRUNC(local_date, MONTH) <= smr.end_month
  GROUP BY user_name, local_date  
),

base_data AS (
  SELECT gg.*, dm.* EXCEPT (user_name)
  FROM group_goals gg
  INNER JOIN daily_metrics dm ON dm.user_name = gg.user_name
),

user_monthly_averages AS (
  SELECT 
    group_name, 
    user_name, 
    is_primary_group, 
    group_productive_hrs_goal,
    date_month, 
    FORMAT_DATE('%Y-%m', date_month) as monthyear,
    AVG(productive_hrs_day) as avg_productive_hrs_day,
    CASE 
      WHEN AVG(productive_hrs_day) IS NULL THEN 0
      WHEN AVG(productive_hrs_day) >= group_productive_hrs_goal THEN 0
      ELSE (group_productive_hrs_goal - AVG(productive_hrs_day)) / group_productive_hrs_goal
    END as unused_capacity_fte
  FROM base_data
  WHERE productive_hrs_day IS NOT NULL
  GROUP BY group_name, user_name, is_primary_group, group_productive_hrs_goal, date_month
),

monthly_metrics AS (
  SELECT 
    monthyear,
    COUNT(DISTINCT CASE WHEN is_primary_group = true THEN user_name END) as count_of_users,
    COUNT(DISTINCT CASE 
      WHEN is_primary_group = true 
        AND avg_productive_hrs_day < group_productive_hrs_goal 
      THEN user_name 
    END) as users_below_goal,
    COUNT(DISTINCT CASE 
      WHEN is_primary_group = true 
        AND avg_productive_hrs_day < 5 
      THEN user_name 
    END) as users_below_5_productive_hrs,
    ROUND(
      SAFE_DIVIDE(
        COUNT(DISTINCT CASE 
          WHEN is_primary_group = true 
            AND avg_productive_hrs_day < group_productive_hrs_goal 
          THEN user_name 
        END),
        COUNT(DISTINCT CASE WHEN is_primary_group = true THEN user_name END)
      ) * 100, 
      2
    ) as percent_of_users_below_goal,
    SUM(CASE 
      WHEN is_primary_group = true 
        AND unused_capacity_fte > 0 
      THEN unused_capacity_fte 
      ELSE 0 
    END) AS unused_capacity
  FROM user_monthly_averages
  GROUP BY monthyear
)

SELECT 
  tm.monthyear,
  tm.trend_date,
  tm.month_order,
  COALESCE(mm.count_of_users, 0) as count_of_users,
  COALESCE(mm.users_below_goal, 0) as users_below_goal,
  COALESCE(mm.users_below_5_productive_hrs, 0) as users_below_5_productive_hrs,
  COALESCE(mm.percent_of_users_below_goal, 0) as percent_of_users_below_goal,
  COALESCE(mm.unused_capacity, 0) as unused_capacity,
  unused_capacity/count_of_users as unused_capacity_pct,
  'Last 6 Months' as chart_context,
  LAG(COALESCE(mm.percent_of_users_below_goal, 0)) 
    OVER (ORDER BY tm.month_order) as prev_month_pct,
  COALESCE(mm.percent_of_users_below_goal, 0) - 
    LAG(COALESCE(mm.percent_of_users_below_goal, 0)) 
      OVER (ORDER BY tm.month_order) as pct_change_from_prev_month
FROM trend_months tm
LEFT JOIN monthly_metrics mm ON tm.monthyear = mm.monthyear
ORDER BY tm.month_order
;

Salary

  1. Create a Google Sheets document with two columns: group_name and average_annual_salary. Change the name of the tab to Salary by Team. The name of the document itself does not matter.

 

  1. Repeat the same steps as the Performance by Group data set up, but pick the Financial Loss - Salary Example data source this time

  2. Locate your spreadsheet and select the Salary by Team worksheet within it. Ensure that “Use first row as headers” is selected.
  3. Click Close to exit the data source configuration window

Rejoin data blends

Group_Salary

  1. Navigate to Resource > Manage blends

 

  1. Click Edit on Group_Salary
  2. Click the middle box that shows two circles in a Venn diagram layout (in this example, the box also contains the text "1 condition")

 

  1. Select Left outer for the Join operator, and select group_name for both tables under Join conditions.

 

  1. Click Save, and Save again in the bottom right-hand corner
  2. Use the back arrow at the top to return to the list of Blends

Location_Salary

  • Repeat the same steps as Group_Salary, but select the Location_Salary blend

Productivity_Salary

  • Repeat the same steps as Group_Salary, but select the Productivity_Salary

ConsecutiveMonths_Salary

  • Repeat the same steps as Group_Salary, but select the ConsecutiveMonths_Salary

 

Click Close to exit the data source configuration window

Sharing Reports

  1. Click the Share button to open the sharing menu
  2. Select the gear icon in the top left corner to define access levels to download and print
  3. Once you have completed your desired configuration, add the individuals you want to share the report with and assign them the appropriate permissions

Scheduling Reports

  1. To configure a scheduled delivery of a report, click the drop-down arrow next to the View/Share tab and select Schedule email delivery
  2. Add the recipient's email address(es) and define your desired settings for Pages, Start Time, Repeat (frequency) and Message as shown in the image below
  3. Click Schedule when finished

Learn more

Was this article helpful?
1 out of 1 found this helpful