Просмотр исходного кода

add moving average to query builder

Sven Klemm 7 лет назад
Родитель
Сommit
dabfd88cd9

+ 25 - 18
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;
       }
     }

+ 14 - 3
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;

+ 19 - 0
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,
 };