mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-01 02:43:59 +00:00
query designer - grop filter (having clause)
This commit is contained in:
@@ -36,6 +36,11 @@ export function dumpSqlSelect(dmp: SqlDumper, cmd: Select) {
|
|||||||
dmp.putCollection(', ', cmd.groupBy, (expr) => dumpSqlExpression(dmp, expr));
|
dmp.putCollection(', ', cmd.groupBy, (expr) => dumpSqlExpression(dmp, expr));
|
||||||
dmp.put('&n');
|
dmp.put('&n');
|
||||||
}
|
}
|
||||||
|
if (cmd.having) {
|
||||||
|
dmp.put('&n^having ');
|
||||||
|
dumpSqlCondition(dmp, cmd.having);
|
||||||
|
dmp.put('&n');
|
||||||
|
}
|
||||||
if (cmd.orderBy) {
|
if (cmd.orderBy) {
|
||||||
dmp.put('&n^order ^by ');
|
dmp.put('&n^order ^by ');
|
||||||
dmp.putCollection(', ', cmd.orderBy, (expr) => {
|
dmp.putCollection(', ', cmd.orderBy, (expr) => {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export interface Select {
|
|||||||
orderBy?: OrderByExpression[];
|
orderBy?: OrderByExpression[];
|
||||||
groupBy?: Expression[];
|
groupBy?: Expression[];
|
||||||
where?: Condition;
|
where?: Condition;
|
||||||
|
having?: Condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UpdateField = Expression & { targetColumn: string };
|
export type UpdateField = Expression & { targetColumn: string };
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { dumpSqlSelect, Select, JoinType, Condition, Relation, mergeConditions, Source } from 'dbgate-sqltree';
|
import {
|
||||||
|
dumpSqlSelect,
|
||||||
|
Select,
|
||||||
|
JoinType,
|
||||||
|
Condition,
|
||||||
|
Relation,
|
||||||
|
mergeConditions,
|
||||||
|
Source,
|
||||||
|
ResultField,
|
||||||
|
} from 'dbgate-sqltree';
|
||||||
import { EngineDriver } from 'dbgate-types';
|
import { EngineDriver } from 'dbgate-types';
|
||||||
import { DesignerInfo, DesignerTableInfo, DesignerReferenceInfo, DesignerJoinType } from './types';
|
import { DesignerInfo, DesignerTableInfo, DesignerReferenceInfo, DesignerJoinType } from './types';
|
||||||
import { DesignerComponent } from './DesignerComponentCreator';
|
import { DesignerComponent } from './DesignerComponentCreator';
|
||||||
@@ -93,34 +102,28 @@ export class DesignerQueryDumper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
addGroupConditions(select: Select, tables: DesignerTableInfo[], selectIsGrouped: boolean) {
|
||||||
let res: Select = null;
|
for (const column of this.designer.columns || []) {
|
||||||
for (const component of this.components) {
|
if (!column.groupFilter) continue;
|
||||||
const select = this.dumpComponent(component);
|
const table = (this.designer.tables || []).find((x) => x.designerId == column.designerId);
|
||||||
if (res == null) res = select;
|
if (!table) continue;
|
||||||
else res = mergeSelectsFromDesigner(res, select);
|
if (!tables.find((x) => x.designerId == table.designerId)) continue;
|
||||||
}
|
|
||||||
|
|
||||||
// top level cross join conditions
|
const condition = parseFilter(column.groupFilter, findDesignerFilterType(column, this.designer));
|
||||||
const topLevelTables = this.topLevelTables;
|
if (condition) {
|
||||||
for (const ref of this.designer.references || []) {
|
select.having = mergeConditions(
|
||||||
if (referenceIsCrossJoin(ref) && referenceIsConnecting(ref, topLevelTables, topLevelTables)) {
|
select.having,
|
||||||
res.where = mergeConditions(res.where, {
|
_.cloneDeepWith(condition, (expr) => {
|
||||||
conditionType: 'and',
|
if (expr.exprType == 'placeholder') {
|
||||||
conditions: getReferenceConditions(ref, this.designer),
|
return this.getColumnOutputExpression(column, selectIsGrouped);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
const topLevelColumns = (this.designer.columns || []).filter((col) =>
|
|
||||||
topLevelTables.find((tbl) => tbl.designerId == col.designerId)
|
|
||||||
);
|
);
|
||||||
const selectIsGrouped = !!topLevelColumns.find((x) => x.isGrouped || (x.aggregate && x.aggregate != '---'));
|
}
|
||||||
const outputColumns = topLevelColumns.filter((x) => x.isOutput);
|
}
|
||||||
if (outputColumns.length == 0) {
|
}
|
||||||
res.selectAll = true;
|
|
||||||
} else {
|
getColumnOutputExpression(col, selectIsGrouped): ResultField {
|
||||||
res.columns = outputColumns.map((col) => {
|
|
||||||
const source = findQuerySource(this.designer, col.designerId);
|
const source = findQuerySource(this.designer, col.designerId);
|
||||||
const { columnName } = col;
|
const { columnName } = col;
|
||||||
let { alias } = col;
|
let { alias } = col;
|
||||||
@@ -150,8 +153,37 @@ export class DesignerQueryDumper {
|
|||||||
source,
|
source,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
let res: Select = null;
|
||||||
|
for (const component of this.components) {
|
||||||
|
const select = this.dumpComponent(component);
|
||||||
|
if (res == null) res = select;
|
||||||
|
else res = mergeSelectsFromDesigner(res, select);
|
||||||
|
}
|
||||||
|
|
||||||
|
// top level cross join conditions
|
||||||
|
const topLevelTables = this.topLevelTables;
|
||||||
|
for (const ref of this.designer.references || []) {
|
||||||
|
if (referenceIsCrossJoin(ref) && referenceIsConnecting(ref, topLevelTables, topLevelTables)) {
|
||||||
|
res.where = mergeConditions(res.where, {
|
||||||
|
conditionType: 'and',
|
||||||
|
conditions: getReferenceConditions(ref, this.designer),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const topLevelColumns = (this.designer.columns || []).filter((col) =>
|
||||||
|
topLevelTables.find((tbl) => tbl.designerId == col.designerId)
|
||||||
|
);
|
||||||
|
const selectIsGrouped = !!topLevelColumns.find((x) => x.isGrouped || (x.aggregate && x.aggregate != '---'));
|
||||||
|
const outputColumns = topLevelColumns.filter((x) => x.isOutput);
|
||||||
|
if (outputColumns.length == 0) {
|
||||||
|
res.selectAll = true;
|
||||||
|
} else {
|
||||||
|
res.columns = outputColumns.map((col) => this.getColumnOutputExpression(col, selectIsGrouped));
|
||||||
|
}
|
||||||
|
|
||||||
const groupedColumns = topLevelColumns.filter((x) => x.isGrouped);
|
const groupedColumns = topLevelColumns.filter((x) => x.isGrouped);
|
||||||
if (groupedColumns.length > 0) {
|
if (groupedColumns.length > 0) {
|
||||||
@@ -176,6 +208,7 @@ export class DesignerQueryDumper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.addConditions(res, topLevelTables);
|
this.addConditions(res, topLevelTables);
|
||||||
|
this.addGroupConditions(res, topLevelTables, selectIsGrouped);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ export default function QueryDesignColumns({ value, onChange }) {
|
|||||||
[onChange]
|
[onChange]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const hasGroupedColumn = !!(columns || []).find((x) => x.isGrouped);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableControl rows={columns || []}>
|
<TableControl rows={columns || []}>
|
||||||
<TableColumn fieldName="columnName" header="Column/Expression" />
|
<TableColumn fieldName="columnName" header="Column/Expression" />
|
||||||
@@ -136,6 +138,21 @@ export default function QueryDesignColumns({ value, onChange }) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
{hasGroupedColumn && (
|
||||||
|
<TableColumn
|
||||||
|
fieldName="groupFilter"
|
||||||
|
header="Group filter"
|
||||||
|
formatter={(row) => (
|
||||||
|
<DataFilterControl
|
||||||
|
filterType={findDesignerFilterType(row, value)}
|
||||||
|
filter={row.groupFilter}
|
||||||
|
setFilter={(groupFilter) => {
|
||||||
|
changeColumn({ ...row, groupFilter });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<TableColumn
|
<TableColumn
|
||||||
fieldName="actions"
|
fieldName="actions"
|
||||||
header=""
|
header=""
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ export type DesignerColumnInfo = {
|
|||||||
aggregate?: string;
|
aggregate?: string;
|
||||||
isOutput?: boolean;
|
isOutput?: boolean;
|
||||||
sortOrder?: number;
|
sortOrder?: number;
|
||||||
filter: string;
|
filter?: string;
|
||||||
|
groupFilter?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DesignerInfo = {
|
export type DesignerInfo = {
|
||||||
|
|||||||
Reference in New Issue
Block a user