Whether it is a personal need to understand your spending pattern from looking at the bank transactions, or seeking to improve the sales performance in your organization by looking at the sales activities, the real insights are only visible with additional aggregation and summarization of the transactional level data. Traditional RDBMS provides this capability through the expressive power of the SQL aggregation. Window functions was added to the ANSI SQL standard to further extend the ability to express more complex questions with the SQL construct.
Couchbase N1QL now supports the window functions and common table expression (CTE) in its 6.5 release. Developers can extend their applications to meet more complex business use cases, as well as empowering data analysts to get the answers they need without performing additional post processing in Excel.
For this article I will focus on couple of examples on how you can leverage N1QL Window functions and CTE to address two very common business questions.
Sales activities duration by customers
In this first example for a sales activity management system, we want to provide a report to show the amount of time that the sales team has spent working with their customers for January-2019. I will break the query down into two steps:
1) Get a list of meetings and the meeting duration that the sales team has conducted with their customers. The total time spent for all customers ‘total_time_spent’ is calculated by summing the duration of the appointments with an empty OVER () clause, which will perform the summing for the entire result set. The total time spent by customer ‘account_time_spent’ uses the same construct, but with the ‘accid’ for the PARTITION clause.
1 2 3 4 5 6 7 8 |
SELECT c.name, a.startDate, a.title, a.duration, SUM(a.duration) OVER() as total_time_spent, SUM(a.duration) OVER(PARTITION BY a.accid) AS account_time_spent FROM crm a INNER JOIN crm c ON a.accid = c.id AND c.type='account' WHERE a.type='activity' AND a.activityType='Appointment' AND a.startDate BETWEEN '2018-01-01' and '2018-01-31' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
account_time_spent duration name startDate title total_time_spent 30 "30" "Smith, Avila and Cisneros" "2018-01-24 15:00:00" "Switchable coherent adapter" 25770 510 "150" "Riddle Ltd" "2018-01-05 15:30:00" "Streamlined intermediate intranet" 25770 510 "90" "Riddle Ltd" "2018-01-28 14:30:00" "Advanced solution-oriented synergy" 25770 510 "90" "Riddle Ltd" "2018-01-01 15:00:00" "Ameliorated object-oriented methodology" 25770 510 "30" "Riddle Ltd" "2018-01-10 08:00:00" "Object-based multi-state firmware" 25770 510 "150" "Riddle Ltd" "2018-01-23 09:00:00" "Multi-layered systematic software" 25770 120 "30" "Foster Inc" "2018-01-29 09:30:00" "Public-key bottom-line database" 25770 120 "30" "Foster Inc" "2018-01-09 13:00:00" "Quality-focused local emulation" 25770 120 "60" "Foster Inc" "2018-01-02 08:00:00" "Digitized motivating matrix" 25770 120 "30" "Williams Ltd" "2018-01-22 08:30:00" "Versatile heuristic workforce" 25770 120 "30" "Williams Ltd" "2018-01-24 13:30:00" "Front-line 4thgeneration help-desk" 25770 120 "60" "Williams Ltd" "2018-01-14 14:30:00" "Visionary upward-trending success" 25770 330 "150" "Reid Ltd" "2018-01-21 10:30:00" "Profound logistical archive" 25770 330 "30" "Reid Ltd" "2018-01-13 13:30:00" "Down-sized coherent access" 25770 330 "120" "Reid Ltd" "2018-01-02 12:00:00" "Front-line object-oriented moderator" 25770 330 "30" "Reid Ltd" "2018-01-12 09:30:00" "Programmable reciprocal infrastructure" 25770 .... |
2) Then use the two metrics to derive the percentage of the overall time the team spent with each customer.
1 2 3 4 5 6 7 8 9 10 |
SELECT c.name, ROUND(( SUM(SUM(a.duration)) OVER(PARTITION BY a.accid) / SUM(SUM(a.duration)) OVER()),2) as pct_time FROM crm a INNER JOIN crm c ON a.accid = c.id AND c.type='account' WHERE a.type='activity' AND a.activityType='Appointment' AND a.startDate BETWEEN '2018-01-01' and '2018-01-31' GROUP BY c.name, a.accid ORDER BY 2 DESC |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
name pct_time "Johnson, Adams and Kelly" 0.17 "Davis Group" 0.08 "Gilbert-Morris" 0.08 "Torres and Sons" 0.07 "Reid Ltd" 0.07 "Medina-Daniels" 0.07 "Riddle Ltd" 0.05 "Henderson and Sons" 0.05 "Gill and Sons" 0.05 "Garcia-Young" 0.05 "Sullivan PLC" 0.03 "Brown-Rogers" 0.03 "Foster Inc" 0.03 "Wheeler Inc" 0.03 "Jarvis-Small" 0.03 "Jones-Fox" 0.03 "Lloyd, Blair and Pruitt" 0.03 "Vaughn LLC" 0.02 |
Sales Activities Month-over-Month
In this second example, the query shows how the number of sales related tasks have changed month over month for the year 2018. The query leverages N1QL CTE feature to improve readability of the query, an also the LAG window function to obtain the previous period task count.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
WITH current_period_task AS ( SELECT DATE_TRUNC_STR(a.startDate,'month') AS month, COUNT(1) AS current_period_task_count FROM crm a WHERE a.type='activity' AND a.activityType = 'Task' AND DATE_PART_STR(a.startDate,'year') = 2018 GROUP BY DATE_TRUNC_STR(a.startDate,'month') ), last_period_task AS ( SELECT x.month, x.current_period_task_count, LAG(x.current_period_task_count) OVER ( ORDER BY x.month) AS last_period_task_count FROM current_period_task x ) SELECT b.month, b.current_period_task_count, ROUND(((b.current_period_task_count - b.last_period_task_count ) / b.last_period_task_count),2) AS MoMChg FROM last_period_task AS b |
- The first CTE – ‘current_period_task’ defines the query to retrieve a count for all activity of type Task group by the calendar month.
- The second CTE – ‘last_period_task’ reads from the first CTE, and also leverage the window function LAG to return the task_count for the previous month. Note that the ORDER BY clause is critical for the LAG function to work.
- The main query reads from the second CTE – ‘last_period_task’ and derive the month over month calculation.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
MoMChg current_period_task_count month 283 "2018-01-01" -0.08 260 "2018-02-01" 0.1 287 "2018-03-01" -0.08 264 "2018-04-01" 0.11 292 "2018-05-01" 0 293 "2018-06-01" -0.03 285 "2018-07-01" 0 285 "2018-08-01" 0 284 "2018-09-01" 0 283 "2018-10-01" -0.05 268 "2018-11-01" 0.06 285 "2018-12-01" |
Resources
- Download:Â Download Couchbase Server 6.5
- Documentation: Couchbase Server 6.5 What’s New
- All 6.5 Blogs
We would love to hear from you on how you liked the 6.5 features and how it’ll benefit your business going forward. Please share your feedback via the comments or in the forum.