Skip to content

Commit 87617c3

Browse files
committed
Add nested JOIN example to README and tests
Add documentation and test example demonstrating how to use BuilderAs to create nested JOIN queries. This is useful when joining with filtered or transformed datasets. fix #217
1 parent 2aef540 commit 87617c3

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- [Build SQL for different systems](#build-sql-for-different-systems)
1616
- [Using `Struct` as a light weight ORM](#using-struct-as-a-light-weight-orm)
1717
- [Nested SQL](#nested-sql)
18+
- [Nested `JOIN`](#nested-join)
1819
- [Use `sql.Named` in a builder](#use-sqlnamed-in-a-builder)
1920
- [Argument modifiers](#argument-modifiers)
2021
- [Freestyle builder](#freestyle-builder)
@@ -348,6 +349,38 @@ fmt.Println(args)
348349
// [4 1]
349350
```
350351

352+
### Nested `JOIN`
353+
354+
In addition to nested subqueries, you can also use `BuilderAs` to create nested JOINs. This is particularly useful when you need to join with a filtered or transformed dataset.
355+
356+
Here is an example showing how to join a table with a nested subquery:
357+
358+
```go
359+
sb := sqlbuilder.NewSelectBuilder()
360+
nestedSb := sqlbuilder.NewSelectBuilder()
361+
362+
// Build the nested subquery
363+
nestedSb.Select("b.id", "b.user_id")
364+
nestedSb.From("users2 AS b")
365+
nestedSb.Where(nestedSb.GreaterThan("b.age", 20))
366+
367+
// Build the main query with nested join
368+
sb.Select("a.id", "a.user_id")
369+
sb.From("users AS a")
370+
sb.Join(
371+
sb.BuilderAs(nestedSb, "b"),
372+
"a.user_id = b.user_id",
373+
)
374+
375+
sql, args := sb.Build()
376+
fmt.Println(sql)
377+
fmt.Println(args)
378+
379+
// Output:
380+
// SELECT a.id, a.user_id FROM users AS a JOIN (SELECT b.id, b.user_id FROM users2 AS b WHERE b.age > ?) AS b ON a.user_id = b.user_id
381+
// [20]
382+
```
383+
351384
### Use `sql.Named` in a builder
352385

353386
The `sql.Named` function, as defined in the `database/sql` package, facilitates the creation of named arguments within SQL statements. This feature is essential for scenarios where an argument needs to be reused multiple times within a single SQL statement. Incorporating named arguments into a builder is straightforward: treat them as regular arguments.

select_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,32 @@ func ExampleSelectBuilder_join() {
117117
// [1 2 5 %Du 86400]
118118
}
119119

120+
func ExampleSelectBuilder_nestedJoin() {
121+
sb := NewSelectBuilder()
122+
nestedSb := NewSelectBuilder()
123+
124+
// Build the nested subquery
125+
nestedSb.Select("b.id", "b.user_id")
126+
nestedSb.From("users2 AS b")
127+
nestedSb.Where(nestedSb.GreaterThan("b.age", 20))
128+
129+
// Build the main query with nested join
130+
sb.Select("a.id", "a.user_id")
131+
sb.From("users AS a")
132+
sb.Join(
133+
sb.BuilderAs(nestedSb, "b"),
134+
"a.user_id = b.user_id",
135+
)
136+
137+
sql, args := sb.Build()
138+
fmt.Println(sql)
139+
fmt.Println(args)
140+
141+
// Output:
142+
// SELECT a.id, a.user_id FROM users AS a JOIN (SELECT b.id, b.user_id FROM users2 AS b WHERE b.age > ?) AS b ON a.user_id = b.user_id
143+
// [20]
144+
}
145+
120146
func ExampleSelectBuilder_limit_offset() {
121147
flavors := []Flavor{MySQL, PostgreSQL, SQLite, SQLServer, CQL, ClickHouse, Presto, Oracle, Informix, Doris}
122148
results := make([][]string, len(flavors))

0 commit comments

Comments
 (0)