From bc2ceb4f3dec78610657b08287cfbb7ee290b6f1 Mon Sep 17 00:00:00 2001 From: Huan Du Date: Sun, 1 Dec 2024 03:25:59 +0800 Subject: [PATCH] fix #181: Support LATERAL keyword --- select.go | 5 +++++ select_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/select.go b/select.go index 123fcc7..5047324 100644 --- a/select.go +++ b/select.go @@ -286,6 +286,11 @@ func (sb *SelectBuilder) BuilderAs(builder Builder, alias string) string { return fmt.Sprintf("(%s) AS %s", sb.Var(builder), alias) } +// LateralAs returns a LATERAL derived table expression wrapping a complex SQL. +func (sb *SelectBuilder) LateralAs(builder Builder, alias string) string { + return fmt.Sprintf("LATERAL (%s) AS %s", sb.Var(builder), alias) +} + // NumCol returns the number of columns to select. func (sb *SelectBuilder) NumCol() int { return len(sb.selectCols) diff --git a/select_test.go b/select_test.go index c31064d..6fbd973 100644 --- a/select_test.go +++ b/select_test.go @@ -388,3 +388,29 @@ func TestSelectBuilderGetFlavor(t *testing.T) { flavor = sbClick.Flavor() a.Equal(ClickHouse, flavor) } + +func ExampleSelectBuilder_LateralAs() { + // Demo SQL comes from a sample on https://dev.mysql.com/doc/refman/8.4/en/lateral-derived-tables.html. + sb := Select( + "salesperson.name", + "max_sale.amount", + "max_sale.customer_name", + ) + sb.From( + "salesperson", + sb.LateralAs( + Select("amount", "customer_name"). + From("all_sales"). + Where( + "all_sales.salesperson_id = salesperson.id", + ). + OrderBy("amount").Desc().Limit(1), + "max_sale", + ), + ) + + fmt.Println(sb) + + // Output: + // SELECT salesperson.name, max_sale.amount, max_sale.customer_name FROM salesperson, LATERAL (SELECT amount, customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id ORDER BY amount DESC LIMIT 1) AS max_sale +}