Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗goSpRlJn 222 of 280 menu
◀ ▶

Соединение строк таблиц в Go

Когда данные разнесены по таблицам, отчет часто требует поля с обеих сторон. Внутреннее соединение складывает строки двух таблиц, у которых совпал ключ: номер в дочерней строке равен номеру в родительской.

Условие совпадения пишут после слова ON. Псевдонимы таблиц сокращают имена столбцов в длинном тексте запроса.

Выведем каждый заказ вместе с именем владельца:

package main import ( "database/sql" "fmt" "log" "os" _ "modernc.org/sqlite" ) func main() { os.Remove("shop.db") db, err := sql.Open("sqlite", "shop.db") if err != nil { log.Fatal(err) } defer db.Close() _, err = db.Exec("PRAGMA foreign_keys = ON") if err != nil { log.Fatal(err) } _, err = db.Exec(` CREATE TABLE users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL ) `) if err != nil { log.Fatal(err) } _, err = db.Exec(` CREATE TABLE orders ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, title TEXT NOT NULL, FOREIGN KEY (user_id) REFERENCES users (id) ) `) if err != nil { log.Fatal(err) } _, err = db.Exec(`INSERT INTO users (name) VALUES (?)`, "ann") if err != nil { log.Fatal(err) } _, err = db.Exec( `INSERT INTO orders (user_id, title) VALUES (?, ?)`, 1, "pen", ) if err != nil { log.Fatal(err) } _, err = db.Exec( `INSERT INTO orders (user_id, title) VALUES (?, ?)`, 1, "book", ) if err != nil { log.Fatal(err) } rows, err := db.Query(` SELECT u.name, o.title FROM orders o INNER JOIN users u ON o.user_id = u.id ORDER BY o.id `) if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { var userName string var orderTitle string err = rows.Scan(&userName, &orderTitle) if err != nil { log.Fatal(err) } fmt.Println(userName, orderTitle) } err = rows.Err() if err != nil { log.Fatal(err) } }

Фильтр по имени пользователя ставят в WHERE уже после соединения:

package main import ( "database/sql" "fmt" "log" "os" _ "modernc.org/sqlite" ) func main() { os.Remove("shop.db") db, err := sql.Open("sqlite", "shop.db") if err != nil { log.Fatal(err) } defer db.Close() _, err = db.Exec("PRAGMA foreign_keys = ON") if err != nil { log.Fatal(err) } _, err = db.Exec(` CREATE TABLE users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL ) `) if err != nil { log.Fatal(err) } _, err = db.Exec(` CREATE TABLE orders ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, title TEXT NOT NULL, FOREIGN KEY (user_id) REFERENCES users (id) ) `) if err != nil { log.Fatal(err) } _, err = db.Exec(`INSERT INTO users (name) VALUES (?)`, "ann") if err != nil { log.Fatal(err) } _, err = db.Exec(`INSERT INTO users (name) VALUES (?)`, "bob") if err != nil { log.Fatal(err) } _, err = db.Exec( `INSERT INTO orders (user_id, title) VALUES (?, ?)`, 1, "pen", ) if err != nil { log.Fatal(err) } _, err = db.Exec( `INSERT INTO orders (user_id, title) VALUES (?, ?)`, 2, "lamp", ) if err != nil { log.Fatal(err) } rows, err := db.Query(` SELECT o.title FROM orders o INNER JOIN users u ON o.user_id = u.id WHERE u.name = ? `, "ann") if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { var orderTitle string err = rows.Scan(&orderTitle) if err != nil { log.Fatal(err) } fmt.Println(orderTitle) } err = rows.Err() if err != nil { log.Fatal(err) } }

Даны таблицы и данные:

CREATE TABLE users ( id INTEGER PRIMARY KEY, name TEXT NOT NULL ); CREATE TABLE orders ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, title TEXT NOT NULL, FOREIGN KEY (user_id) REFERENCES users (id) ); INSERT INTO users (name) VALUES ('ann'); INSERT INTO orders (user_id, title) VALUES (1, 'pen');

Напишите запрос, который выведет имя пользователя и название заказа в одной строке результата для каждой пары.

Даны таблицы garages и vehicles с полем garage_id у машины. Составьте текст запроса, который выведет код гаража и номер машины для каждой связанной пары.

Даны те же users и orders, что в примере с фильтром. Опишите словами, какие заказы попадут в выборку, если в условии имя "bob".

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить