# Selecting * [Creating a SelectDataset](#create) * Building SQL * [`Select`](#select) * [`Distinct`](#distinct) * [`From`](#from) * [`Join`](#joins) * [`Where`](#where) * [`Limit`](#limit) * [`Offset`](#offset) * [`GroupBy`](#group_by) * [`Having`](#having) * [`Window`](#window) * [`With`](#with) * [`SetError`](#seterror) * [`ForUpdate`](#forupdate) * Executing Queries * [`ScanStructs`](#scan-structs) - Scans rows into a slice of structs * [`ScanStruct`](#scan-struct) - Scans a row into a slice a struct, returns false if a row wasnt found * [`ScanVals`](#scan-vals)- Scans a rows of 1 column into a slice of primitive values * [`ScanVal`](#scan-val) - Scans a row of 1 column into a primitive value, returns false if a row wasnt found. * [`Scanner`](#scanner) - Allows you to interatively scan rows into structs or values. * [`Count`](#count) - Returns the count for the current query * [`Pluck`](#pluck) - Selects a single column and stores the results into a slice of primitive values To create a [`SelectDataset`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset) you can use **[`goqu.From`](https://godoc.org/github.com/doug-martin/goqu/#From) and [`goqu.Select`](https://godoc.org/github.com/doug-martin/goqu/#Select)** When you just want to create some quick SQL, this mostly follows the `Postgres` with the exception of placeholders for prepared statements. ```go sql, _, _ := goqu.From("table").ToSQL() fmt.Println(sql) sql, _, _ := goqu.Select(goqu.L("NOW()")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "table" SELECT NOW() ``` **[`DialectWrapper.From`](https://godoc.org/github.com/doug-martin/goqu/#DialectWrapper.From) and [`DialectWrapper.Select`](https://godoc.org/github.com/doug-martin/goqu/#DialectWrapper.Select)** Use this when you want to create SQL for a specific `dialect` ```go // import _ "github.com/doug-martin/goqu/v9/dialect/mysql" dialect := goqu.Dialect("mysql") sql, _, _ := dialect.From("table").ToSQL() fmt.Println(sql) sql, _, _ := dialect.Select(goqu.L("NOW()")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM `table` SELECT NOW() ``` **[`Database.From`](https://godoc.org/github.com/doug-martin/goqu/#DialectWrapper.From) and [`Database.Select`](https://godoc.org/github.com/doug-martin/goqu/#DialectWrapper.From)** Use this when you want to execute the SQL or create SQL for the drivers dialect. ```go // import _ "github.com/doug-martin/goqu/v9/dialect/mysql" mysqlDB := //initialize your db db := goqu.New("mysql", mysqlDB) sql, _, _ := db.From("table").ToSQL() fmt.Println(sql) sql, _, _ := db.Select(goqu.L("NOW()")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM `table` SELECT NOW() ``` ### Examples For more examples visit the **[Docs](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset)** **[`Select`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Select)** ```go sql, _, _ := goqu.From("test").Select("a", "b", "c").ToSQL() fmt.Println(sql) ``` Output: ```sql SELECT "a", "b", "c" FROM "test" ``` You can also ues another dataset in your select ```go ds := goqu.From("test") fromDs := ds.Select("age").Where(goqu.C("age").Gt(10)) sql, _, _ := ds.From().Select(fromDs).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT (SELECT "age" FROM "test" WHERE ("age" > 10)) ``` Selecting a literal ```go sql, _, _ := goqu.From("test").Select(goqu.L("a + b").As("sum")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT a + b AS "sum" FROM "test" ``` Select aggregate functions ```go sql, _, _ := goqu.From("test").Select( goqu.COUNT("*").As("age_count"), goqu.MAX("age").As("max_age"), goqu.AVG("age").As("avg_age"), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT COUNT(*) AS "age_count", MAX("age") AS "max_age", AVG("age") AS "avg_age" FROM "test" ``` Selecting columns from a struct ```go ds := goqu.From("test") type myStruct struct { Name string Address string `db:"address"` EmailAddress string `db:"email_address"` } // Pass with pointer sql, _, _ := ds.Select(&myStruct{}).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT "address", "email_address", "name" FROM "test" ``` **[`Distinct`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Distinct)** ```go sql, _, _ := goqu.From("test").Select("a", "b").Distinct().ToSQL() fmt.Println(sql) ``` Output: ``` SELECT DISTINCT "a", "b" FROM "test" ``` If you dialect supports `DISTINCT ON` you provide arguments to the `Distinct` method. **NOTE** currently only the `postgres` and the default dialects support `DISTINCT ON` clauses ```go sql, _, _ := goqu.From("test").Distinct("a").ToSQL() fmt.Println(sql) ``` Output: ``` SELECT DISTINCT ON ("a") * FROM "test" ``` You can also provide other expression arguments With `goqu.L` ```go sql, _, _ := goqu.From("test").Distinct(goqu.L("COALESCE(?, ?)", goqu.C("a"), "empty")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT DISTINCT ON (COALESCE("a", 'empty')) * FROM "test" ``` With `goqu.Coalesce` ```go sql, _, _ := goqu.From("test").Distinct(goqu.COALESCE(goqu.C("a"), "empty")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT DISTINCT ON (COALESCE("a", 'empty')) * FROM "test" ``` **[`From`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.From)** Overriding the original from ```go ds := goqu.From("test") sql, _, _ := ds.From("test2").ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test2" ``` From another dataset ```go ds := goqu.From("test") fromDs := ds.Where(goqu.C("age").Gt(10)) sql, _, _ := ds.From(fromDs).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM (SELECT * FROM "test" WHERE ("age" > 10)) AS "t1" ``` From an aliased dataset ```go ds := goqu.From("test") fromDs := ds.Where(goqu.C("age").Gt(10)) sql, _, _ := ds.From(fromDs.As("test2")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM (SELECT * FROM "test" WHERE ("age" > 10)) AS "test2" ``` Lateral Query ```go maxEntry := goqu.From("entry"). Select(goqu.MAX("int").As("max_int")). Where(goqu.Ex{"time": goqu.Op{"lt": goqu.I("e.time")}}). As("max_entry") maxId := goqu.From("entry"). Select("id"). Where(goqu.Ex{"int": goqu.I("max_entry.max_int")}). As("max_id") ds := goqu. Select("e.id", "max_entry.max_int", "max_id.id"). From( goqu.T("entry").As("e"), goqu.Lateral(maxEntry), goqu.Lateral(maxId), ) query, args, _ := ds.ToSQL() fmt.Println(query, args) query, args, _ = ds.Prepared(true).ToSQL() fmt.Println(query, args) ``` Output ``` SELECT "e"."id", "max_entry"."max_int", "max_id"."id" FROM "entry" AS "e", LATERAL (SELECT MAX("int") AS "max_int" FROM "entry" WHERE ("time" < "e"."time")) AS "max_entry", LATERAL (SELECT "id" FROM "entry" WHERE ("int" = "max_entry"."max_int")) AS "max_id" [] SELECT "e"."id", "max_entry"."max_int", "max_id"."id" FROM "entry" AS "e", LATERAL (SELECT MAX("int") AS "max_int" FROM "entry" WHERE ("time" < "e"."time")) AS "max_entry", LATERAL (SELECT "id" FROM "entry" WHERE ("int" = "max_entry"."max_int")) AS "max_id" [] ``` **[`Join`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Join)** ```go sql, _, _ := goqu.From("test").Join( goqu.T("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")}), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" INNER JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`InnerJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.InnerJoin) ```go sql, _, _ := goqu.From("test").InnerJoin( goqu.T("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")}), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" INNER JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`FullOuterJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.FullOuterJoin) ```go sql, _, _ := goqu.From("test").FullOuterJoin( goqu.T("test2"), goqu.On(goqu.Ex{ "test.fkey": goqu.I("test2.Id"), }), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" FULL OUTER JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`RightOuterJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.RightOuterJoin) ```go sql, _, _ := goqu.From("test").RightOuterJoin( goqu.T("test2"), goqu.On(goqu.Ex{ "test.fkey": goqu.I("test2.Id"), }), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" RIGHT OUTER JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`LeftOuterJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.LeftOuterJoin) ```go sql, _, _ := goqu.From("test").LeftOuterJoin( goqu.T("test2"), goqu.On(goqu.Ex{ "test.fkey": goqu.I("test2.Id"), }), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" LEFT OUTER JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`FullJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.FullJoin) ```go sql, _, _ := goqu.From("test").FullJoin( goqu.T("test2"), goqu.On(goqu.Ex{ "test.fkey": goqu.I("test2.Id"), }), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" FULL JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`RightJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.RightJoin) ```go sql, _, _ := goqu.From("test").RightJoin( goqu.T("test2"), goqu.On(goqu.Ex{ "test.fkey": goqu.I("test2.Id"), }), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" RIGHT JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`LeftJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.LeftJoin) ```go sql, _, _ := goqu.From("test").LeftJoin( goqu.T("test2"), goqu.On(goqu.Ex{ "test.fkey": goqu.I("test2.Id"), }), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" LEFT JOIN "test2" ON ("test"."fkey" = "test2"."Id") ``` [`NaturalJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.NaturalJoin) ```go sql, _, _ := goqu.From("test").NaturalJoin(goqu.T("test2")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" NATURAL JOIN "test2" ``` [`NaturalLeftJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.NaturalLeftJoin) ```go sql, _, _ := goqu.From("test").NaturalLeftJoin(goqu.T("test2")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" NATURAL LEFT JOIN "test2" ``` [`NaturalRightJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.NaturalRightJoin) ```go sql, _, _ := goqu.From("test").NaturalRightJoin(goqu.T("test2")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" NATURAL RIGHT LEFT JOIN "test2" ``` [`NaturalFullJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.NaturalFullJoin) ```go sql, _, _ := goqu.From("test").NaturalFullJoin(goqu.T("test2")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" NATURAL FULL LEFT JOIN "test2" ``` [`CrossJoin`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.CrossJoin) ```go sql, _, _ := goqu.From("test").CrossJoin(goqu.T("test2")).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" CROSS JOIN "test2" ``` Join with a Lateral ```go maxEntry := goqu.From("entry"). Select(goqu.MAX("int").As("max_int")). Where(goqu.Ex{"time": goqu.Op{"lt": goqu.I("e.time")}}). As("max_entry") maxId := goqu.From("entry"). Select("id"). Where(goqu.Ex{"int": goqu.I("max_entry.max_int")}). As("max_id") ds := goqu. Select("e.id", "max_entry.max_int", "max_id.id"). From(goqu.T("entry").As("e")). Join(goqu.Lateral(maxEntry), goqu.On(goqu.V(true))). Join(goqu.Lateral(maxId), goqu.On(goqu.V(true))) query, args, _ := ds.ToSQL() fmt.Println(query, args) query, args, _ = ds.Prepared(true).ToSQL() fmt.Println(query, args) ``` Output: ``` SELECT "e"."id", "max_entry"."max_int", "max_id"."id" FROM "entry" AS "e" INNER JOIN LATERAL (SELECT MAX("int") AS "max_int" FROM "entry" WHERE ("time" < "e"."time")) AS "max_entry" ON TRUE INNER JOIN LATERAL (SELECT "id" FROM "entry" WHERE ("int" = "max_entry"."max_int")) AS "max_id" ON TRUE [] SELECT "e"."id", "max_entry"."max_int", "max_id"."id" FROM "entry" AS "e" INNER JOIN LATERAL (SELECT MAX("int") AS "max_int" FROM "entry" WHERE ("time" < "e"."time")) AS "max_entry" ON ? INNER JOIN LATERAL (SELECT "id" FROM "entry" WHERE ("int" = "max_entry"."max_int")) AS "max_id" ON ? [true true] ``` **[`Where`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Where)** You can use `goqu.Ex` to create an ANDed condition ```go sql, _, _ := goqu.From("test").Where(goqu.Ex{ "a": goqu.Op{"gt": 10}, "b": goqu.Op{"lt": 10}, "c": nil, "d": []string{"a", "b", "c"}, }).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" WHERE (("a" > 10) AND ("b" < 10) AND ("c" IS NULL) AND ("d" IN ('a', 'b', 'c'))) ``` You can use `goqu.ExOr` to create an ORed condition ```go sql, _, _ := goqu.From("test").Where(goqu.ExOr{ "a": goqu.Op{"gt": 10}, "b": goqu.Op{"lt": 10}, "c": nil, "d": []string{"a", "b", "c"}, }).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" WHERE (("a" > 10) OR ("b" < 10) OR ("c" IS NULL) OR ("d" IN ('a', 'b', 'c'))) ``` You can use `goqu.Ex` with `goqu.ExOr` for complex expressions ```go // You can use Or with Ex to Or multiple Ex maps together sql, _, _ := goqu.From("test").Where( goqu.Or( goqu.Ex{ "a": goqu.Op{"gt": 10}, "b": goqu.Op{"lt": 10}, }, goqu.Ex{ "c": nil, "d": []string{"a", "b", "c"}, }, ), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" WHERE ((("a" > 10) AND ("b" < 10)) OR (("c" IS NULL) AND ("d" IN ('a', 'b', 'c')))) ``` You can also use identifiers to create your where condition ```go sql, _, _ := goqu.From("test").Where( goqu.C("a").Gt(10), goqu.C("b").Lt(10), goqu.C("c").IsNull(), goqu.C("d").In("a", "b", "c"), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" WHERE (("a" > 10) AND ("b" < 10) AND ("c" IS NULL) AND ("d" IN ('a', 'b', 'c'))) ``` Using `goqu.Or` to create ORed expression ```go // You can use a combination of Ors and Ands sql, _, _ := goqu.From("test").Where( goqu.Or( goqu.C("a").Gt(10), goqu.And( goqu.C("b").Lt(10), goqu.C("c").IsNull(), ), ), ).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" WHERE (("a" > 10) OR (("b" < 10) AND ("c" IS NULL))) ``` **[`Limit`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Limit)** ```go ds := goqu.From("test").Limit(10) sql, _, _ := ds.ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" LIMIT 10 ``` **[`Offset`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Offset)** ```go ds := goqu.From("test").Offset(2) sql, _, _ := ds.ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" OFFSET 2 ``` **[`GroupBy`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.GroupBy)** ```go sql, _, _ := goqu.From("test"). Select(goqu.SUM("income").As("income_sum")). GroupBy("age"). ToSQL() fmt.Println(sql) ``` Output: ``` SELECT SUM("income") AS "income_sum" FROM "test" GROUP BY "age" ``` **[`Having`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Having)** ```go sql, _, _ = goqu.From("test").GroupBy("age").Having(goqu.SUM("income").Gt(1000)).ToSQL() fmt.Println(sql) ``` Output: ``` SELECT * FROM "test" GROUP BY "age" HAVING (SUM("income") > 1000) ``` **[`With`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.With)** To use CTEs in `SELECT` statements you can use the `With` method. Simple Example ```go sql, _, _ := goqu.From("one"). With("one", goqu.From().Select(goqu.L("1"))). Select(goqu.Star()). ToSQL() fmt.Println(sql) ``` Output: ``` WITH one AS (SELECT 1) SELECT * FROM "one" ``` Dependent `WITH` clauses: ```go sql, _, _ = goqu.From("derived"). With("intermed", goqu.From("test").Select(goqu.Star()).Where(goqu.C("x").Gte(5))). With("derived", goqu.From("intermed").Select(goqu.Star()).Where(goqu.C("x").Lt(10))). Select(goqu.Star()). ToSQL() fmt.Println(sql) ``` Output: ``` WITH intermed AS (SELECT * FROM "test" WHERE ("x" >= 5)), derived AS (SELECT * FROM "intermed" WHERE ("x" < 10)) SELECT * FROM "derived" ``` `WITH` clause with arguments ```go sql, _, _ = goqu.From("multi"). With("multi(x,y)", goqu.From().Select(goqu.L("1"), goqu.L("2"))). Select(goqu.C("x"), goqu.C("y")). ToSQL() fmt.Println(sql) ``` Output: ``` WITH multi(x,y) AS (SELECT 1, 2) SELECT "x", "y" FROM "multi" ``` Using a `InsertDataset`. ```go insertDs := goqu.Insert("foo").Rows(goqu.Record{"user_id": 10}).Returning("id") ds := goqu.From("bar"). With("ins", insertDs). Select("bar_name"). Where(goqu.Ex{"bar.user_id": goqu.I("ins.user_id")}) sql, _, _ := ds.ToSQL() fmt.Println(sql) sql, args, _ := ds.Prepared(true).ToSQL() fmt.Println(sql, args) ``` Output: ``` WITH ins AS (INSERT INTO "foo" ("user_id") VALUES (10) RETURNING "id") SELECT "bar_name" FROM "bar" WHERE ("bar"."user_id" = "ins"."user_id") WITH ins AS (INSERT INTO "foo" ("user_id") VALUES (?) RETURNING "id") SELECT "bar_name" FROM "bar" WHERE ("bar"."user_id" = "ins"."user_id") [10] ``` Using an `UpdateDataset` ```go updateDs := goqu.Update("foo").Set(goqu.Record{"bar": "baz"}).Returning("id") ds := goqu.From("bar"). With("upd", updateDs). Select("bar_name"). Where(goqu.Ex{"bar.user_id": goqu.I("ins.user_id")}) sql, _, _ := ds.ToSQL() fmt.Println(sql) sql, args, _ := ds.Prepared(true).ToSQL() fmt.Println(sql, args) ``` Output: ``` WITH upd AS (UPDATE "foo" SET "bar"='baz' RETURNING "id") SELECT "bar_name" FROM "bar" WHERE ("bar"."user_id" = "upd"."user_id") WITH upd AS (UPDATE "foo" SET "bar"=? RETURNING "id") SELECT "bar_name" FROM "bar" WHERE ("bar"."user_id" = "upd"."user_id") [baz] ``` Using a `DeleteDataset` ```go deleteDs := goqu.Delete("foo").Where(goqu.Ex{"bar": "baz"}).Returning("id") ds := goqu.From("bar"). With("del", deleteDs). Select("bar_name"). Where(goqu.Ex{"bar.user_id": goqu.I("del.user_id")}) sql, _, _ := ds.ToSQL() fmt.Println(sql) sql, args, _ := ds.Prepared(true).ToSQL() fmt.Println(sql, args) ``` Output: ``` WITH del AS (DELETE FROM "foo" WHERE ("bar" = 'baz') RETURNING "id") SELECT "bar_name" FROM "bar" WHERE ("bar"."user_id" = "del"."user_id") WITH del AS (DELETE FROM "foo" WHERE ("bar" = ?) RETURNING "id") SELECT "bar_name" FROM "bar" WHERE ("bar"."user_id" = "del"."user_id") [baz] ``` **[`Window Function`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.Window)** **NOTE** currently only the `postgres`, `mysql8` (NOT `mysql`) and the default dialect support `Window Function` To use windowing in `SELECT` statements you can use the `Over` method on an `SQLFunction` ```go sql, _, _ := goqu.From("test").Select( goqu.ROW_NUMBER().Over(goqu.W().PartitionBy("a").OrderBy(goqu.I("b").Asc())), ) fmt.Println(sql) ``` Output: ``` SELECT ROW_NUMBER() OVER (PARTITION BY "a" ORDER BY "b") FROM "test" ``` `goqu` also supports the `WINDOW` clause. ```go sql, _, _ := goqu.From("test"). Select(goqu.ROW_NUMBER().OverName(goqu.I("w"))). Window(goqu.W("w").PartitionBy("a").OrderBy(goqu.I("b").Asc())) fmt.Println(sql) ``` Output: ``` SELECT ROW_NUMBER() OVER "w" FROM "test" WINDOW "w" AS (PARTITION BY "a" ORDER BY "b") ``` **[`SetError`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.SetError)** Sometimes while building up a query with goqu you will encounter situations where certain preconditions are not met or some end-user contraint has been violated. While you could track this error case separately, goqu provides a convenient built-in mechanism to set an error on a dataset if one has not already been set to simplify query building. Set an Error on a dataset: ```go func GetSelect(name string) *goqu.SelectDataset { var ds = goqu.From("test") if len(name) == 0 { return ds.SetError(fmt.Errorf("name is empty")) } return ds.Select(name) } ``` This error is returned on any subsequent call to `Error` or `ToSQL`: ```go var name string = "" ds = GetSelect(name) fmt.Println(ds.Error()) sql, args, err = ds.ToSQL() fmt.Println(err) ``` Output: ``` name is empty name is empty ``` **[`ForUpdate`](https://godoc.org/github.com/doug-martin/goqu/#SelectDataset.ForUpdate)** ```go sql, _, _ := goqu.From("test").ForUpdate(exp.Wait).ToSQL() fmt.Println(sql) ``` Output: ```sql SELECT * FROM "test" FOR UPDATE ``` If your dialect supports FOR UPDATE OF you provide tables to be locked as variable arguments to the ForUpdate method. ```go sql, _, _ := goqu.From("test").ForUpdate(exp.Wait, goqu.T("test")).ToSQL() fmt.Println(sql) ``` Output: ```sql SELECT * FROM "test" FOR UPDATE OF "test" ``` ## Executing Queries To execute your query use [`goqu.Database#From`](https://godoc.org/github.com/doug-martin/goqu/#Database.From) to create your dataset **[`ScanStructs`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.ScanStructs)** Scans rows into a slice of structs **NOTE** [`ScanStructs`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.ScanStructs) will only select the columns that can be scanned in to the structs unless you have explicitly selected certain columns. ```go type User struct{ FirstName string `db:"first_name"` LastName string `db:"last_name"` Age int `db:"-"` // a field that shouldn't be selected } var users []User //SELECT "first_name", "last_name" FROM "user"; if err := db.From("user").ScanStructs(&users); err != nil{ panic(err.Error()) } fmt.Printf("\n%+v", users) var users []User //SELECT "first_name" FROM "user"; if err := db.From("user").Select("first_name").ScanStructs(&users); err != nil{ panic(err.Error()) } fmt.Printf("\n%+v", users) ``` `goqu` also supports scanning into multiple structs. In the example below we define a `Role` and `User` struct that could both be used individually to scan into. However, you can also create a new struct that adds both structs as fields that can be populated in a single query. **NOTE** When calling `ScanStructs` without a select already defined it will automatically only `SELECT` the columns found in the struct, omitting any that are tagged with `db:"-"` ```go type Role struct { Id uint64 `db:"id"` UserID uint64 `db:"user_id"` Name string `db:"name"` } type User struct { Id uint64 `db:"id"` FirstName string `db:"first_name"` LastName string `db:"last_name"` } type UserAndRole struct { User User `db:"goqu_user"` // tag as the "goqu_user" table Role Role `db:"user_role"` // tag as "user_role" table } db := getDb() ds := db. From("goqu_user"). Join(goqu.T("user_role"), goqu.On(goqu.I("goqu_user.id").Eq(goqu.I("user_role.user_id")))) var users []UserAndRole // Scan structs will auto build the if err := ds.ScanStructs(&users); err != nil { fmt.Println(err.Error()) return } for _, u := range users { fmt.Printf("\n%+v", u) } ``` You can alternatively manually select the columns with the appropriate aliases using the `goqu.C` method to create the alias. ```go type Role struct { UserID uint64 `db:"user_id"` Name string `db:"name"` } type User struct { Id uint64 `db:"id"` FirstName string `db:"first_name"` LastName string `db:"last_name"` Role Role `db:"user_role"` // tag as "user_role" table } db := getDb() ds := db. Select( "goqu_user.id", "goqu_user.first_name", "goqu_user.last_name", // alias the fully qualified identifier `C` is important here so it doesnt parse it goqu.I("user_role.user_id").As(goqu.C("user_role.user_id")), goqu.I("user_role.name").As(goqu.C("user_role.name")), ). From("goqu_user"). Join(goqu.T("user_role"), goqu.On(goqu.I("goqu_user.id").Eq(goqu.I("user_role.user_id")))) var users []User if err := ds.ScanStructs(&users); err != nil { fmt.Println(err.Error()) return } for _, u := range users { fmt.Printf("\n%+v", u) } ``` **[`ScanStruct`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.ScanStruct)** Scans a row into a slice a struct, returns false if a row wasnt found **NOTE** [`ScanStruct`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.ScanStruct) will only select the columns that can be scanned in to the struct unless you have explicitly selected certain columns. ```go type User struct{ FirstName string `db:"first_name"` LastName string `db:"last_name"` Age int `db:"-"` // a field that shouldn't be selected } var user User // SELECT "first_name", "last_name" FROM "user" LIMIT 1; found, err := db.From("user").ScanStruct(&user) if err != nil{ fmt.Println(err.Error()) return } if !found { fmt.Println("No user found") } else { fmt.Printf("\nFound user: %+v", user) } ``` `goqu` also supports scanning into multiple structs. In the example below we define a `Role` and `User` struct that could both be used individually to scan into. However, you can also create a new struct that adds both structs as fields that can be populated in a single query. **NOTE** When calling `ScanStruct` without a select already defined it will automatically only `SELECT` the columns found in the struct, omitting any that are tagged with `db:"-"` ```go type Role struct { UserID uint64 `db:"user_id"` Name string `db:"name"` } type User struct { ID uint64 `db:"id"` FirstName string `db:"first_name"` LastName string `db:"last_name"` } type UserAndRole struct { User User `db:"goqu_user"` // tag as the "goqu_user" table Role Role `db:"user_role"` // tag as "user_role" table } db := getDb() var userAndRole UserAndRole ds := db. From("goqu_user"). Join(goqu.T("user_role"),goqu.On(goqu.I("goqu_user.id").Eq(goqu.I("user_role.user_id")))). Where(goqu.C("first_name").Eq("Bob")) found, err := ds.ScanStruct(&userAndRole) if err != nil{ fmt.Println(err.Error()) return } if !found { fmt.Println("No user found") } else { fmt.Printf("\nFound user: %+v", user) } ``` You can alternatively manually select the columns with the appropriate aliases using the `goqu.C` method to create the alias. ```go type Role struct { UserID uint64 `db:"user_id"` Name string `db:"name"` } type User struct { ID uint64 `db:"id"` FirstName string `db:"first_name"` LastName string `db:"last_name"` Role Role `db:"user_role"` // tag as "user_role" table } db := getDb() var userAndRole UserAndRole ds := db. Select( "goqu_user.id", "goqu_user.first_name", "goqu_user.last_name", // alias the fully qualified identifier `C` is important here so it doesnt parse it goqu.I("user_role.user_id").As(goqu.C("user_role.user_id")), goqu.I("user_role.name").As(goqu.C("user_role.name")), ). From("goqu_user"). Join(goqu.T("user_role"),goqu.On(goqu.I("goqu_user.id").Eq(goqu.I("user_role.user_id")))). Where(goqu.C("first_name").Eq("Bob")) found, err := ds.ScanStruct(&userAndRole) if err != nil{ fmt.Println(err.Error()) return } if !found { fmt.Println("No user found") } else { fmt.Printf("\nFound user: %+v", user) } ``` **NOTE** Using the `goqu.SetColumnRenameFunction` function, you can change the function that's used to rename struct fields when struct tags aren't defined ```go import "strings" goqu.SetColumnRenameFunction(strings.ToUpper) type User struct{ FirstName string LastName string } var user User //SELECT "FIRSTNAME", "LASTNAME" FROM "user" LIMIT 1; found, err := db.From("user").ScanStruct(&user) // ... ``` **NOTE** Using the `goqu.SetIgnoreUntaggedFields(true)` function, you can cause goqu to ignore any fields that aren't explicitly tagged. ```go goqu.SetIgnoreUntaggedFields(true) type User struct{ FirstName string `db:"first_name"` LastName string } var user User //SELECT "first_name" FROM "user" LIMIT 1; found, err := db.From("user").ScanStruct(&user) // ... ``` **[`ScanVals`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.ScanVals)** Scans a rows of 1 column into a slice of primitive values ```go var ids []int64 if err := db.From("user").Select("id").ScanVals(&ids); err != nil{ fmt.Println(err.Error()) return } fmt.Printf("\n%+v", ids) ``` [`ScanVal`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.ScanVal) Scans a row of 1 column into a primitive value, returns false if a row wasnt found. **Note** when using the dataset a `LIMIT` of 1 is automatically applied. ```go var id int64 found, err := db.From("user").Select("id").ScanVal(&id) if err != nil{ fmt.Println(err.Error()) return } if !found{ fmt.Println("No id found") }else{ fmt.Printf("\nFound id: %d", id) } ``` **[`Scanner`](http://godoc.org/github.com/doug-martin/goqu/exec#Scanner)** Scanner knows how to scan rows into structs. This is useful when dealing with large result sets where you can have only one item scanned in memory at one time. In the following example we scan each row into struct. ```go type User struct { FirstName string `db:"first_name"` LastName string `db:"last_name"` } db := getDb() scanner, err := db. From("goqu_user"). Select("first_name", "last_name"). Where(goqu.Ex{ "last_name": "Yukon", }). Executor(). Scanner() if err != nil { fmt.Println(err.Error()) return } defer scanner.Close() for scanner.Next() { u := User{} err = scanner.ScanStruct(&u) if err != nil { fmt.Println(err.Error()) return } fmt.Printf("\n%+v", u) } if scanner.Err() != nil { fmt.Println(scanner.Err().Error()) } ``` In this example we scan each row into a val. ```go db := getDb() scanner, err := db. From("goqu_user"). Select("first_name"). Where(goqu.Ex{ "last_name": "Yukon", }). Executor(). Scanner() if err != nil { fmt.Println(err.Error()) return } defer scanner.Close() for scanner.Next() { name := "" err = scanner.ScanVal(&name) if err != nil { fmt.Println(err.Error()) return } fmt.Println(name) } if scanner.Err() != nil { fmt.Println(scanner.Err().Error()) } ``` **[`Count`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.Count)** Returns the count for the current query ```go count, err := db.From("user").Count() if err != nil{ fmt.Println(err.Error()) return } fmt.Printf("\nCount:= %d", count) ``` **[`Pluck`](http://godoc.org/github.com/doug-martin/goqu#SelectDataset.Pluck)** Selects a single column and stores the results into a slice of primitive values ```go var ids []int64 if err := db.From("user").Pluck(&ids, "id"); err != nil{ fmt.Println(err.Error()) return } fmt.Printf("\nIds := %+v", ids) ```