From dabfd88cd9eaadf55467f34118a37a021bf0b63b Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Fri, 3 Aug 2018 07:44:36 +0200 Subject: [PATCH] add moving average to query builder --- .../datasource/postgres/postgres_query.ts | 43 +++++++++++-------- .../plugins/datasource/postgres/query_ctrl.ts | 17 ++++++-- .../plugins/datasource/postgres/sql_part.ts | 19 ++++++++ 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/public/app/plugins/datasource/postgres/postgres_query.ts b/public/app/plugins/datasource/postgres/postgres_query.ts index fb6fa59ada1..d5bdf005e8f 100644 --- a/public/app/plugins/datasource/postgres/postgres_query.ts +++ b/public/app/plugins/datasource/postgres/postgres_query.ts @@ -142,7 +142,7 @@ export default class PostgresQuery { query = columnName.params[0]; let aggregate = _.find(column, (g: any) => g.type === 'aggregate' || g.type === 'percentile'); - let windows = _.find(column, (g: any) => g.type === 'window'); + let windows = _.find(column, (g: any) => g.type === 'window' || g.type === 'moving_window'); if (aggregate) { let func = aggregate.params[0]; @@ -174,25 +174,32 @@ export default class PostgresQuery { let over = overParts.join(' '); let curr: string; let prev: string; - switch (windows.params[0]) { - case 'increase': - curr = query; - prev = 'lag(' + curr + ') OVER (' + over + ')'; - query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; - break; - case 'rate': - let timeColumn = this.target.timeColumn; - if (aggregate) { - timeColumn = 'min(' + timeColumn + ')'; + switch (windows.type) { + case 'window': + switch (windows.params[0]) { + case 'increase': + curr = query; + prev = 'lag(' + curr + ') OVER (' + over + ')'; + query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; + break; + case 'rate': + let timeColumn = this.target.timeColumn; + if (aggregate) { + timeColumn = 'min(' + timeColumn + ')'; + } + + curr = query; + prev = 'lag(' + curr + ') OVER (' + over + ')'; + query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; + query += '/extract(epoch from ' + timeColumn + ' - lag(' + timeColumn + ') OVER (' + over + '))'; + break; + default: + query = windows.params[0] + '(' + query + ') OVER (' + over + ')'; + break; } - - curr = query; - prev = 'lag(' + curr + ') OVER (' + over + ')'; - query = '(CASE WHEN ' + curr + ' >= ' + prev + ' THEN ' + curr + ' - ' + prev + ' ELSE ' + curr + ' END)'; - query += '/extract(epoch from ' + timeColumn + ' - lag(' + timeColumn + ') OVER (' + over + '))'; break; - default: - query = windows.params[0] + '(' + query + ') OVER (' + over + ')'; + case 'moving_window': + query = windows.params[0] + '(' + query + ') OVER (' + over + ' ROWS ' + windows.params[1] + ' PRECEDING)'; break; } } diff --git a/public/app/plugins/datasource/postgres/query_ctrl.ts b/public/app/plugins/datasource/postgres/query_ctrl.ts index a5867cd09f6..6138896d42a 100644 --- a/public/app/plugins/datasource/postgres/query_ctrl.ts +++ b/public/app/plugins/datasource/postgres/query_ctrl.ts @@ -138,6 +138,7 @@ export class PostgresQueryCtrl extends QueryCtrl { { text: 'Increase', value: 'increase' }, { text: 'Rate', value: 'rate' }, { text: 'Sum', value: 'sum' }, + { text: 'Moving Average', value: 'avg', type: 'moving_window' }, ], }; this.selectMenu.push(windows); @@ -263,14 +264,22 @@ export class PostgresQueryCtrl extends QueryCtrl { return _.findIndex(selectParts, (p: any) => p.def.type === 'aggregate' || p.def.type === 'percentile'); } + findWindowIndex(selectParts) { + return _.findIndex(selectParts, (p: any) => p.def.type === 'window' || p.def.type === 'moving_window'); + } + addSelectPart(selectParts, item, subItem) { - let partModel = sqlPart.create({ type: item.value }); + let partType = item.value; + if (subItem && subItem.type) { + partType = subItem.type; + } + let partModel = sqlPart.create({ type: partType }); if (subItem) { partModel.params = [subItem.value]; } let addAlias = false; - switch (item.value) { + switch (partType) { case 'column': let parts = _.map(selectParts, function(part: any) { return sqlPart.create({ type: part.def.type, params: _.clone(part.params) }); @@ -295,8 +304,10 @@ export class PostgresQueryCtrl extends QueryCtrl { addAlias = true; } break; + case 'moving_window': + partModel.params.push('5'); case 'window': - let windowIndex = _.findIndex(selectParts, (p: any) => p.def.type === 'window'); + let windowIndex = this.findWindowIndex(selectParts); if (windowIndex !== -1) { // replace current window function selectParts[windowIndex] = partModel; diff --git a/public/app/plugins/datasource/postgres/sql_part.ts b/public/app/plugins/datasource/postgres/sql_part.ts index 9cf0bd8f425..52ede10dad9 100644 --- a/public/app/plugins/datasource/postgres/sql_part.ts +++ b/public/app/plugins/datasource/postgres/sql_part.ts @@ -113,6 +113,25 @@ register({ defaultParams: ['increase'], }); +register({ + type: 'moving_window', + style: 'label', + label: 'Moving Window:', + params: [ + { + name: 'function', + type: 'string', + options: ['avg'], + }, + { + name: 'window_size', + type: 'number', + options: ['3', '5', '7', '10', '20'], + }, + ], + defaultParams: ['avg', '5'], +}); + export default { create: createPart, };