<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jeremiah Oseremi Mayaki </title>
    <description>The latest articles on DEV Community by Jeremiah Oseremi Mayaki  (@omeiza_mayaki).</description>
    <link>https://dev.to/omeiza_mayaki</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3144750%2Fb9cf7e4c-2aca-4819-88f2-69cf1f83c3f7.jpg</url>
      <title>DEV Community: Jeremiah Oseremi Mayaki </title>
      <link>https://dev.to/omeiza_mayaki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omeiza_mayaki"/>
    <language>en</language>
    <item>
      <title>Spark Augmented Reality (AR) Filter Engagement Metrics</title>
      <dc:creator>Jeremiah Oseremi Mayaki </dc:creator>
      <pubDate>Mon, 19 May 2025 12:29:40 +0000</pubDate>
      <link>https://dev.to/omeiza_mayaki/spark-augmented-reality-ar-filter-engagement-metrics-1446</link>
      <guid>https://dev.to/omeiza_mayaki/spark-augmented-reality-ar-filter-engagement-metrics-1446</guid>
      <description>&lt;p&gt;I recently completed an SQL challenge on the interviewmaster.ai platform involving a scenario where I am the data analyst in the marketing analytics team at Meta and have been tasked with evaluating the performance of branded AR filters with the aim of identifying which filters are driving the highest user interactions and shares to inform future campaign strategies for brands using the Spark AR platform. By analyzing engagement data, my team aims to provide actionable insights that will enhance campaign effectiveness and audience targeting. &lt;br&gt;
I completed this challenge using SQLite.&lt;/p&gt;

&lt;p&gt;I was provided with 2 tables:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ar_filters: containing the filter_id and the filter_name fields&lt;/li&gt;
&lt;li&gt;ar_filters_engagements containing the engagement_id, filter_id, interaction_count and engagement_date fields &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Challenge 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was required to query the dataset to return the AR filters that have generated (at least 1) user interactions in July 2024 by their filter names.&lt;/p&gt;

&lt;p&gt;This challenge required me to; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve the filter names. &lt;/li&gt;
&lt;li&gt;Use the SUM() aggregate function.&lt;/li&gt;
&lt;li&gt;Join the two tables using the filter_id as the common field in both tables.&lt;/li&gt;
&lt;li&gt;Filter the result based on the required date using the strftime() function.&lt;/li&gt;
&lt;li&gt;Order the result by the total interaction count.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT f.filter_id, 
  f.filter_name,
  SUM(e.interaction_count) AS total_interaction_count
FROM ar_filters AS f
JOIN ar_filter_engagements AS e
  ON f.filter_id = e.filter_id
WHERE strftime('%Y', e.engagement_date) = '2024'
  AND strftime('%m', e.engagement_date) = '07'
GROUP BY f.filter_id, f.filter_name
ORDER BY total_interaction_count DESC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn64vjmo1t3v1ieoqqahe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn64vjmo1t3v1ieoqqahe.png" alt="challenge 1 image" width="711" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was required to get how many total interactions each AR filter received in August 2024, and to return only filter names that received over 1000 interactions, and their respective interaction counts.&lt;/p&gt;

&lt;p&gt;This challenge required me to use the HAVING clause to selectively filter out only the AR filters that have more than 1000 engagements.&lt;/p&gt;

&lt;p&gt;Although, this seems like a filter function that could have been done using the WHERE statement, SQL does not support using an aggregate function &lt;em&gt;SUM(e.interaction_count)&lt;/em&gt; in this case, hence the reason why we had to use the HAVING clause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; SELECT f.filter_id, 
  f.filter_name,
  SUM(e.interaction_count) AS total_interaction_count
FROM ar_filters AS f
JOIN ar_filter_engagements AS e
  ON f.filter_id = e.filter_id
WHERE strftime('%Y', e.engagement_date) = '2024'
  AND strftime('%m', e.engagement_date) = '08'
GROUP BY f.filter_id, f.filter_name
   HAVING SUM(e.interaction_count) &amp;gt; 1000
ORDER BY total_interaction_count DESC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9gkdr26pqyz1evxokj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9gkdr26pqyz1evxokj0.png" alt="challenge 2" width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenge 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the third and last challenge, I was required to write a query that returns the top 3 AR filters with the highest number of interactions in September 2024 and show how many interactions each filter received.&lt;/p&gt;

&lt;p&gt;All I had to do was to edit the query that solved the second task. I removed the HAVING clause (since this challenge did not require an engagement count limit to be added to the result), and LIMITed my answer to just the top 3 filter names.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; SELECT f.filter_id, 
  f.filter_name,
  SUM(e.interaction_count) AS total_interaction_count
FROM ar_filters AS f
JOIN ar_filter_engagements AS e
  ON f.filter_id = e.filter_id
WHERE strftime('%Y', e.engagement_date) = '2024'
  AND strftime('%m', e.engagement_date) = '09'
GROUP BY f.filter_id, f.filter_name
ORDER BY total_interaction_count DESC
LIMIT 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqltny9hlp8n0wyem6m2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqltny9hlp8n0wyem6m2f.png" alt="challenge 3" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Overall, it was a thrilling challenge which required some serious analytical thinking. &lt;/p&gt;

&lt;p&gt;What do you think about it? Recommendations are highly welcome.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>sqlite</category>
      <category>dataanalytics</category>
    </item>
    <item>
      <title>Taxi Drivers Efficiency Analysis with SQL &amp; Tableau</title>
      <dc:creator>Jeremiah Oseremi Mayaki </dc:creator>
      <pubDate>Sat, 10 May 2025 11:16:07 +0000</pubDate>
      <link>https://dev.to/omeiza_mayaki/driver-efficiency-analysis-with-sql-tableau-24ej</link>
      <guid>https://dev.to/omeiza_mayaki/driver-efficiency-analysis-with-sql-tableau-24ej</guid>
      <description>&lt;p&gt;I recently completed a hands-on SQL project using the Chicago Taxi Trips dataset on BigQuery, where I calculated taxi drivers' efficiency based on total fare earned per minute spent on trips for a single day.&lt;/p&gt;

&lt;p&gt;🧠 What I Did:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Queried the dataset with a Common Table Expression (CTE):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most useful SQL features I leveraged in this project was the Common Table Expression (CTE). &lt;/p&gt;

&lt;p&gt;A CTE lets you create a temporary, named result set that can be referenced within your main query. For me, it makes my SQL logic far more readable and manageable. &lt;/p&gt;

&lt;p&gt;Instead of cramming all calculations into one long block of code, I broke things down step by step—calculating total trip duration, number of trips, and total fare inside the CTE. This made the final SELECT query cleaner, easier to debug, and more efficient to run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Creating a CTE
WITH table_mains AS (
  SELECT
    taxi_id,
    SUM (TIMESTAMP_DIFF(trip_end_timestamp, trip_start_timestamp, MINUTE)) AS total_trip_duration,
    COUNT (*) AS trip_count,
    SUM (fare) AS total_fare
  FROM
    `bigquery-public-data.chicago_taxi_trips.taxi_trips`
  WHERE
    DATE (trip_start_timestamp) = '2013-10-03'

# Filtering out rows that could have problems so as to get a clean result
    AND (fare) is NOT NULL
    AND (TIMESTAMP_DIFF(trip_end_timestamp, trip_start_timestamp, MINUTE)) &amp;gt; 0
  GROUP BY taxi_id
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.Filtered out incomplete or unrealistic data while creating the CTE:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To ensure accurate results and insights, I filtered out rows with missing fare values and zero trip durations. This step is crucial—it prevents skewed efficiency scores and keeps the analysis reliable&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Filtering out rows that could have problems so as to get a clean result
    AND (fare) is NOT NULL
    AND (TIMESTAMP_DIFF(trip_end_timestamp, trip_start_timestamp, MINUTE)) &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Calculated key metrics: total trip duration, total fare, number of trips, and efficiency score and ranked drivers based on their efficiency score:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I calculated key performance metrics like total trip duration, total fare, and trip count. &lt;/p&gt;

&lt;p&gt;Using SAFE_DIVIDE, I computed the efficiency score (fare per minute) to avoid errors from division by zero. Then, I applied the RANK() window function to rank drivers based on this score—making it easy to identify the most efficient drivers at a glance.&lt;/p&gt;

&lt;p&gt;Also, I used the WHERE clause to extract results for drivers that had more than 5 trips and ordered the results by efficiency rank.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT 
  taxi_id,
  total_trip_duration,
  trip_count,
  total_fare,
  SAFE_DIVIDE (total_fare, trip_count) AS avg_trip_cost,
  SAFE_DIVIDE (total_fare, total_trip_duration) AS efficiency_score,
  RANK () OVER (
    ORDER BY SAFE_DIVIDE (total_fare, total_trip_duration) DESC
  ) AS efficiency_rank
FROM 
  table_mains

# Say we want to see the results for taxis that travelled more than 5 trips
WHERE
  trip_count &amp;gt;= 5
ORDER BY efficiency_score DESC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📊 Results:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After running the query and getting my query result, I saved the result and went ahead to import the saved result into Tableau to create a visualization and draw insights from the result.&lt;/p&gt;

&lt;p&gt;The visualization brings the data to life—making it easy to compare driver performance at a glance with its interactivity. It also helps stakeholders quickly identify top performers and make data-driven decisions with clarity&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5pquvpf6fmriksjkm1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5pquvpf6fmriksjkm1c.png" alt="Query result" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2du9zfptwtb9ghee0oj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2du9zfptwtb9ghee0oj5.png" alt="Tableau result" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧪 Tools Used:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;SQL (Google BigQuery Sandbox)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tableau (for visualization)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;💭 Reflection:&lt;/strong&gt;&lt;br&gt;
This project helped me reinforce my understanding of analytic functions like SAFE_DIVIDE() and RANK(), and taught me how to turn raw data into actionable insights.&lt;/p&gt;

&lt;p&gt;What do you think of this approach? Feedback and ideas are welcome!&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>sql</category>
      <category>tableau</category>
      <category>data</category>
      <category>bigquery</category>
    </item>
  </channel>
</rss>
