Skip to content

Commit 1f5c6aa

Browse files
authored
Merge pull request #24 from ejyager00/subquery-join
Allow use of subqueries in join clauses
2 parents 501f540 + b47631b commit 1f5c6aa

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

src/Builder.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,11 @@ export class QueryBuilder<GenericResult, GenericResultOne> {
204204
const joinQuery: Array<string> = []
205205
value.forEach((item: Join) => {
206206
const type = item.type ? `${item.type} ` : ''
207-
joinQuery.push(`${type}JOIN ${item.table} ON ${item.on}`)
207+
joinQuery.push(
208+
`${type}JOIN ${typeof item.table === 'string' ? item.table : `(${this._select(item.table)})`}${
209+
item.alias ? ` AS ${item.alias}` : ''
210+
} ON ${item.on}`
211+
)
208212
})
209213

210214
return ' ' + joinQuery.join(' ')

src/interfaces.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ export interface Where {
99

1010
export interface Join {
1111
type?: string | JoinTypes
12-
table: string
12+
table: string | SelectAll
1313
on: string
14+
alias?: string
1415
}
1516

1617
export interface SelectOne {

test/Builder.test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,67 @@ describe('QueryBuilder', () => {
444444
)
445445
})
446446

447+
test('select with subquery join', async () => {
448+
const query = new QuerybuilderTest()._select({
449+
tableName: 'testTable',
450+
fields: '*',
451+
where: {
452+
conditions: 'field = ?1',
453+
params: ['test'],
454+
},
455+
join: {
456+
table: {
457+
tableName: 'otherTable',
458+
fields: ['test_table_id', 'GROUP_CONCAT(attribute) AS attributes'],
459+
groupBy: 'test_table_id',
460+
},
461+
on: 'testTable.id = otherTableGrouped.test_table_id',
462+
alias: 'otherTableGrouped',
463+
},
464+
})
465+
466+
expect(query).toEqual(
467+
'SELECT * FROM testTable JOIN (SELECT test_table_id, GROUP_CONCAT(attribute) AS attributes FROM otherTable GROUP BY test_table_id) AS otherTableGrouped ON testTable.id = otherTableGrouped.test_table_id WHERE field = ?1'
468+
)
469+
})
470+
471+
test('select with nested subquery joins', async () => {
472+
const query = new QuerybuilderTest()._select({
473+
tableName: 'testTable',
474+
fields: '*',
475+
where: {
476+
conditions: 'field = ?1',
477+
params: ['test'],
478+
},
479+
join: {
480+
table: {
481+
tableName: 'otherTable',
482+
fields: [
483+
'test_table_id',
484+
'GROUP_CONCAT(attribute) AS attributes',
485+
'GROUP_CONCAT(other_attributes, ";") AS other_attributes',
486+
],
487+
groupBy: 'test_table_id',
488+
join: {
489+
table: {
490+
tableName: 'otherTableTwo',
491+
fields: ['other_table_id', 'GROUP_CONCAT(other_attribute) AS other_attributes'],
492+
groupBy: 'other_table_id',
493+
},
494+
on: 'otherTable.id = otherTableTwoGrouped.other_table_id',
495+
alias: 'otherTableTwoGrouped',
496+
},
497+
},
498+
on: 'testTable.id = otherTableGrouped.test_table_id',
499+
alias: 'otherTableGrouped',
500+
},
501+
})
502+
503+
expect(query).toEqual(
504+
'SELECT * FROM testTable JOIN (SELECT test_table_id, GROUP_CONCAT(attribute) AS attributes, GROUP_CONCAT(other_attributes, ";") AS other_attributes FROM otherTable JOIN (SELECT other_table_id, GROUP_CONCAT(other_attribute) AS other_attributes FROM otherTableTwo GROUP BY other_table_id) AS otherTableTwoGrouped ON otherTable.id = otherTableTwoGrouped.other_table_id GROUP BY test_table_id) AS otherTableGrouped ON testTable.id = otherTableGrouped.test_table_id WHERE field = ?1'
505+
)
506+
})
507+
447508
test('select with one where no parameters', async () => {
448509
const query = new QuerybuilderTest()._select({
449510
tableName: 'testTable',

0 commit comments

Comments
 (0)