WITH (original) (raw)

Contents

WITH statements provides a way to write auxiliary statements for use in a larger query. These statements, which are often referred to as Common Table Expressions or CTEs, can be thought of as defining temporary tables that exist just for one query. More about WITH statements can be found here:
PostgreSQL - https://www.postgresql.org/docs/12/queries-with.html
MySQL - https://dev.mysql.com/doc/refman/8.0/en/with.html
MariaDB - https://mariadb.com/kb/en/with

How to write WITH statement?

PostgreSQL Example

// CTEs declarations removeDiscontinuedOrders := CTE("remove_discontinued_orders") updateDiscontinuedPrice := CTE("update_discontinued_price") logDiscontinuedProducts := CTE("log_discontinued")

// CTE exported column. Can be used in other CTE(updateDiscontinuedPrice) or in the main CTE. discontinuedProductID := OrderDetails.ProductID.From(removeDiscontinuedOrders)

stmt := WITH( removeDiscontinuedOrders.AS( OrderDetails.DELETE(). WHERE(OrderDetails.ProductID.IN( SELECT(Products.ProductID). FROM(Products). WHERE(Products.Discontinued.EQ(Int(1))) ), ).RETURNING(OrderDetails.ProductID), ), updateDiscontinuedPrice.AS( Products.UPDATE(). SET( Products.UnitPrice.SET(Float(0.0)), ). WHERE(Products.ProductID.IN(removeDiscontinuedOrders.SELECT(discontinuedProductID))). RETURNING(Products.AllColumns), ), logDiscontinuedProducts.AS( ProductLogs.INSERT(ProductLogs.AllColumns). QUERY( SELECT(updateDiscontinuedPrice.AllColumns()). FROM(updateDiscontinuedPrice), ). RETURNING(ProductLogs.AllColumns), ), )( SELECT(logDiscontinuedProducts.AllColumns()). FROM(logDiscontinuedProducts), )

var resp []model.ProductLogs err = stmt.Query(tx, &resp)

Note

More about CTE projection aliasing rules you can be found at Sub-query, since the same logic applies.

MySQL and MariaDB Example

salesRep := CTE("sales_rep") customerSalesRep := CTE("customer_sales_rep")

salesRepStaffID := Staff.StaffID.From(salesRep) salesRepFullName := StringColumn("sales_rep_full_name").From(salesRep)

stmt := WITH( salesRep.AS( SELECT( Staff.StaffID, Staff.FirstName.CONCAT(Staff.LastName).AS(salesRepFullName.Name()), ).FROM(Staff), ), customerSalesRep.AS( SELECT( Customer.FirstName.CONCAT(Customer.LastName).AS("customer_name"), salesRepFullName, ).FROM( salesRep. INNER_JOIN(Store, Store.ManagerStaffID.EQ(salesRepStaffID)). INNER_JOIN(Customer, Customer.StoreID.EQ(Store.StoreID)), ), ), )( SELECT(customerSalesRep.AllColumns()). FROM(customerSalesRep), )

var dest []model.Customer err := stmt.Query(db, &dest)

How to write WITH RECURSIVE statements?

Using RECURSIVE, a WITH query can refer to its own output. The general form of a recursive WITH query is always a non-recursive term, then UNION (or UNION ALL), then a recursive term, where only the recursive term can contain a reference to the query's own output.

subordinates := CTE("subordinates")

stmt := WITH_RECURSIVE( subordinates.AS( SELECT( Employees.AllColumns, ).FROM( Employees, ).WHERE( Employees.EmployeeID.EQ(Int(2)), ).UNION( SELECT( Employees.AllColumns, ).FROM( Employees. INNER_JOIN(subordinates, Employees.EmployeeID.From(subordinates).EQ(Employees.ReportsTo)), ), ), ), )( SELECT( subordinates.AllColumns(), ).FROM( subordinates, ), )