diff --git a/public/app/plugins/datasource/postgres/postgres_query.ts b/public/app/plugins/datasource/postgres/postgres_query.ts index 4cd3ddefaa2..4c9bd862658 100644 --- a/public/app/plugins/datasource/postgres/postgres_query.ts +++ b/public/app/plugins/datasource/postgres/postgres_query.ts @@ -138,16 +138,21 @@ export default class PostgresQuery { let special = _.find(column, (g: any) => g.type === 'window'); if (aggregate) { + let func = aggregate.params[0]; switch (aggregate.type) { case 'aggregate': - if (special) { - query = aggregate.params[0] + '(' + query + ' ORDER BY ' + this.target.timeColumn + ')'; + if (func === 'first' || func === 'last') { + query = func + '(' + query + ',' + this.target.timeColumn + ')'; } else { - query = aggregate.params[0] + '(' + query + ')'; + if (special) { + query = func + '(' + query + ' ORDER BY ' + this.target.timeColumn + ')'; + } else { + query = func + '(' + query + ')'; + } } break; case 'percentile': - query = aggregate.params[0] + '(' + aggregate.params[1] + ') WITHIN GROUP (ORDER BY ' + query + ')'; + query = func + '(' + aggregate.params[1] + ') WITHIN GROUP (ORDER BY ' + query + ')'; break; } } diff --git a/public/app/plugins/datasource/postgres/query_ctrl.ts b/public/app/plugins/datasource/postgres/query_ctrl.ts index 0191d46065f..181a3a9234c 100644 --- a/public/app/plugins/datasource/postgres/query_ctrl.ts +++ b/public/app/plugins/datasource/postgres/query_ctrl.ts @@ -98,38 +98,49 @@ export class PostgresQueryCtrl extends QueryCtrl { } buildSelectMenu() { - this.selectMenu = [ - { - text: 'Aggregate Functions', - value: 'aggregate', - submenu: [ - { text: 'Average', value: 'avg' }, - { text: 'Count', value: 'count' }, - { text: 'Maximum', value: 'max' }, - { text: 'Minimum', value: 'min' }, - { text: 'Sum', value: 'sum' }, - { text: 'Standard deviation', value: 'stddev' }, - { text: 'Variance', value: 'variance' }, - ], - }, - { - text: 'Ordered-Set Aggregate Functions', - value: 'percentile', - submenu: [ - { text: 'Percentile (continuous)', value: 'percentile_cont' }, - { text: 'Percentile (discrete)', value: 'percentile_disc' }, - ], - }, - { - text: 'Window Functions', - value: 'window', - submenu: [ - { text: 'Increase', value: 'increase' }, - { text: 'Rate', value: 'rate' }, - { text: 'Sum', value: 'sum' }, - ], - }, - ]; + this.selectMenu = []; + let aggregates = { + text: 'Aggregate Functions', + value: 'aggregate', + submenu: [ + { text: 'Average', value: 'avg' }, + { text: 'Count', value: 'count' }, + { text: 'Maximum', value: 'max' }, + { text: 'Minimum', value: 'min' }, + { text: 'Sum', value: 'sum' }, + { text: 'Standard deviation', value: 'stddev' }, + { text: 'Variance', value: 'variance' }, + ], + }; + + // first and last are timescaledb specific + aggregates.submenu.push({ text: 'First', value: 'first' }); + aggregates.submenu.push({ text: 'Last', value: 'last' }); + + this.selectMenu.push(aggregates); + + // ordered set aggregates require postgres 9.4+ + let aggregates2 = { + text: 'Ordered-Set Aggregate Functions', + value: 'percentile', + submenu: [ + { text: 'Percentile (continuous)', value: 'percentile_cont' }, + { text: 'Percentile (discrete)', value: 'percentile_disc' }, + ], + }; + this.selectMenu.push(aggregates2); + + let windows = { + text: 'Window Functions', + value: 'window', + submenu: [ + { text: 'Increase', value: 'increase' }, + { text: 'Rate', value: 'rate' }, + { text: 'Sum', value: 'sum' }, + ], + }; + this.selectMenu.push(windows); + this.selectMenu.push({ text: 'Alias', value: 'alias' }); this.selectMenu.push({ text: 'Column', value: 'column' }); }