INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com');
  Go
  u := tables.USERS()
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
  
  SQL
  --------------
-- Postgres --
--------------
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com')
RETURNING u.user_id;
-----------
-- MySQL --
-----------
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com');
SELECT last_insert_id();
  Go
  u := tables.USERS()
var lastInsertID int64
var lastInsertIDs []int64
//----------//
// Postgres //
//----------//
// Note: Postgres is able to return multiple INSERT-ed IDs, not just
// the last inserted one
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    Returning(u.USER_ID).
    ToSQL()
rows, err := DB.Query(query, args...)
if err != nil {
    /* handle error */
}
for rows.Next() {
    err = rows.Scan(&lastInsertID)
    if err != nil {
        /* handle error */
    }
    lastInsertIDs = append(lastInsertIDs, lastInsertID)
}
// ...if you use Returningx (see [Struct Mapping](/sq/basics/struct-mapping.html#select-one-vs-many))
err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    Returningx(func(row *sq.Row) {
        lastInsertID = row.Int64(u.USER_ID)
    }, func() {
        lastInsertIDs = append(lastInsertIDs, lastInsertID)
    }).
    Fetch(DB)
if err != nil {
    /* handle error */
}
// ...if you use ReturningRowx (see [Struct Mapping](/sq/basics/struct-mapping.html#select-one-vs-many))
// ReturningRowx only returns one row, which means in this case it will only
// return the user_id of 'bob'.
err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    ReturningRowx(func(row *sq.Row) {
        lastInsertID = row.Int64(u.USER_ID)
    }).
    Fetch(DB)
if err != nil {
    /* handle error */
}
//-------//
// MySQL //
//-------//
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    Returning(u.USER_ID).
    ToSQL()
res, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
lastInsertID, err := res.LastInsertId() // user_id for 'bob'
if err != nil {
    /* handle error */
}
// ...if you use Exec
lastInsertID, _, err := sq.InsertInto(u) // user_id for 'bob'
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    Exec(DB, sq.ElastInsertID)
if err != nil {
    /* handle error */
}
  
  SQL
  --------------
-- Postgres --
--------------
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com')
ON CONFLICT DO NOTHING;
-----------
-- MySQL --
-----------
-- Ignoring all errors ([including wrong datatype and foreign key errors](https://stackoverflow.com/a/4596409))
-- Only use if you really don't care about any possible errors
INSERT IGNORE INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com');
-- Ignoring duplicates by assigning a column to itself
-- (MySQL will not run UPDATE if the value is the same)
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com')
ON DUPLICATE KEY DO UPDATE email = email;
  Go
  u := tables.USERS()
//----------//
// Postgres //
//----------//
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnConflict().DoNothing().
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnConflict().DoNothing().
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
//-------//
// MySQL //
//-------//
// Ignoring all errors
// ...if you use ToSQL
query, args := sq.InsertIgnoreInto(u)
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, _, err := sq.InsertIgnoreInto(u)
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
// Ignoring duplicates by assigning a column to itself
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnDuplicateKeyUpdate(u.EMAIL.Set(u.EMAIL)).
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, _, err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnDuplicateKeyUpdate(u.EMAIL.Set(u.EMAIL)).
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
  
  SQL
  --------------
-- Postgres --
--------------
-- [postgrestutorial.com: upsert](https://www.postgresqltutorial.com/postgresql-upsert/)
-- Using conflict column(s)
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com')
ON CONFLICT (email) DO UPDATE SET
name = EXCLUDED.name;
-- Using conflict constraint
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com')
ON CONFLICT ON CONSTRAINT users_email_key DO UPDATE SET
name = EXCLUDED.name;
-----------
-- MySQL --
-----------
-- [mysqltutorial.org: upsert](https://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/)
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com'), ('alice', 'alice@email.com')
ON DUPLICATE KEY DO UPDATE
name = VALUES(name);
  Go
  u := tables.USERS()
//----------//
// Postgres //
//----------//
// Using conflict columns(s)
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnConflict(u.EMAIL).
    DoUpdateSet(
        u.NAME.Set(sq.Excluded(u.NAME)),
    ).
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnConflict(u.EMAIL).
    DoUpdateSet(
        u.NAME.Set(sq.Excluded(u.NAME)),
    ).
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
// Using conflict constraint
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnConflictOnConstraint("users_email_key").
    DoUpdateSet(
        u.NAME.Set(sq.Excluded(u.NAME)),
    ).
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnConflictOnConstraint("users_email_key").
    DoUpdateSet(
        u.NAME.Set(sq.Excluded(u.NAME)),
    ).
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
//-------//
// MySQL //
//-------//
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnDuplicateKeyUpdate(
        u.NAME.Set(sq.Values(u.NAME)),
    ).
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, _, err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Values("bob", "bob@email.com").
    Values("alice", "alice@email.com").
    OnDuplicateKeyUpdate(
        u.NAME.Set(sq.Values(u.NAME)),
    ).
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
  
  SQL
  INSERT INTO public.users (name, email)
SELECT name, email
FROM public.users
WHERE users.name = 'bob';
  Go
  u := tables.USERS()
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Select(sq.
        Select(u.NAME, u.EMAIL).
        From(u).
        Where(u.NAME.EqString("bob")),
    ).
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, err := sq.InsertInto(u).
    Columns(u.NAME, u.EMAIL).
    Select(sq.
        Select(u.NAME, u.EMAIL).
        From(u).
        Where(u.NAME.EqString("bob")),
    ).
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
  
  Alternatively, you can bind values to columns in an insert statement. This helps if you are inserting a lot of columns and you don't want to accidentally mess up the order or miss a value.
-- SQL
INSERT INTO public.users (name, email)
VALUES ('bob', 'bob@email.com');
  // Go
u := tables.USERS()
user := User{Name: "bob", Email: "bob@email.com"}
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Valuesx(func(col *sq.Column) {
        col.SetString(u.NAME, user.Name)
        col.SetString(u.EMAIL, user.Email)
    }).
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, err := sq.InsertInto(u).
    Valuesx(func(col *sq.Column) {
        col.SetString(u.NAME, user.Name)
        col.SetString(u.EMAIL, user.Email)
    }).
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
  -- SQL
INSERT INTO public.users (name, email)
VALUES
    ('bob', 'bob@email.com'),
    ('alice', 'alice@email.com'),
    ('eve', 'eve@email.com');
  // Go
u := tables.USERS()
users := []User{
    {Name: "bob",   Email: "bob@email.com"},
    {Name: "alice", Email: "alice@email.com"},
    {Name: "eve",   Email: "eve@email.com"},
}
// ...if you use ToSQL
query, args := sq.InsertInto(u).
    Valuesx(func(col *sq.Column) {
        for _, user := range users {
            col.SetString(u.NAME, user.Name)
            col.SetString(u.EMAIL, user.Email)
        }
    }).
    ToSQL()
_, err := DB.Exec(query, args...)
if err != nil {
    /* handle error */
}
// ...if you use Exec
_, err := sq.InsertInto(u).
    Valuesx(func(col *sq.Column) {
        for _, user := range users {
            col.SetString(u.NAME, user.Name)
            col.SetString(u.EMAIL, user.Email)
        }
    }).
    Exec(DB, 0)
if err != nil {
    /* handle error */
}
  
  Clauses are just struct fields, you can either use method chaining to add clauses or manipulate the struct fields directly.
  var q sq.InsertQuery
// Adding
q = q.With(cte1, cte2, cte3)
// is equivalent to //
q = q.With(cte1).With(cte2).With(cte3)
// is equivalent to //
q.CTEs = []sq.CTE{cte1, cte2, cte3}
// Removing
q.CTEs = nil
    
    var q sq.InsertQuery
// Adding
q = q.InsertInto(table)
// is equivalent to //
q.IntoTable = table
// Removing
q.IntoTable = nil
    var q sq.InsertQuery
// Adding
q = q.InsertIgnoreInto(table)
// is equivalent to //
q.Ignore = true
q.IntoTable = table
// Removing
q.Ignore = false
q.IntoTable = nil
    var q sq.InsertQuery
// Adding
q = q.Columns(field1, field2, field3).
    Values(value1, value2, value3).
    Values(value4, value5, value6)
// is equivalent to //
q = q.InsertRow(field1.Set(value1), field2.Set(value2), field3.Set(value3)).
  InsertRow(field1.Set(value4), field2.Set(value5), field3.Set(value6))
// is equivalent to //
q.InsertColumns = []sq.Field{field1, field2, field3}
q.RowValues = []sq.RowValue{
    {value1, value2, value3},
    {value4, value5, value6},
}
// Removing
q.InsertColumns = nil
q.RowValues = nil
    var q sq.InsertQuery
// Adding
q = q.Select(sq.Select(field1, field2).From(table).Where(predicate)).
// is equivalent to //
subquery := sq.Select(field1, field2).From(table).Where(predicate)
q.SelectQuery = &subquery
// Removing
q.SelectQuery = nil
    var q sq.InsertQuery
// Adding
/* ON CONFLICT DO NOTHING */
q = q.OnConflict().DoNothing()
// is equivalent to //
q.HandleConflict = true
/* ON CONFLICT DO UPDATE */
q = q.OnConflict(field1, field2).DoUpdateSet(assignment1, assignment2)
// is equivalent to //
q.HandleConflict = true
q.ConflictFields = []sq.Field{field1, field2}
q.Resolution = []sq.Assignment{assignment1, assignment2}
/* ON CONFLICT DO UPDATE with predicates */
q = q.OnConflict(field1, field2).
    Where(predicate1).
    DoUpdateSet(assignment1, assignment2).
    Where(predicate2)
// is equivalent to //
q.HandleConflict = true
q.ConflictFields = []sq.Field{field1, field2}
q.ConflictPredicate.Predicates = []sq.Predicate{predicate1}
q.Resolution = []sq.Assignment{assignment1, assignment2}
q.ResolutionPredicate.Predicates = []sq.Predicate{predicate2}
// Removing
q.HandleConflict = false
/* optional */
q.ConflictFields = nil
q.ConflictPredicate.Predicates = nil
q.Resolution = nil
q.ResolutionPredicate.Predicates = nil
    var q sq.InsertQuery
// Adding
q = q.OnDuplicateKeyUpdate(assignment1, assignment2)
// is equivalent to //
q.Resolution = []sq.Assignment{assignment1, assignment2}
// Removing
q.Resolution = nil
    var q sq.InsertQuery
// Adding
q = q.Returning(field1, field2, field3)
// is equivalent to //
q = q.Returning(field1).Returning(field2).Returning(field3)
// is equivalent to //
q.ReturningFields = []sq.Field{field1, field2, field3}
// Removing
q.ReturningFields = nil