Что такое вложенные запросы (subqueries) в SQL и как с ними работать в Go?

Ответ

Вложенный запрос (subquery или nested query) — это SQL-запрос, который находится внутри другого SQL-запроса. Он позволяет создавать более сложные и гибкие выборки данных, используя результат одного запроса как часть условия для другого.

В Go для выполнения таких запросов используется стандартный пакет database/sql или его более продвинутые аналоги (например, pgx).

Пример использования

Предположим, нам нужно найти всех пользователей, которые сделали заказы на сумму более 100. Это можно сделать с помощью вложенного запроса в условии WHERE ... IN:

// db - это ваш экземпляр *sql.DB
rows, err := db.Query(`
    SELECT name, email 
    FROM users 
    WHERE id IN (SELECT user_id FROM orders WHERE amount > ?)
`, 100)
if err != nil {
    log.Fatalf("Query failed: %v", err)
}
defer rows.Close()

for rows.Next() {
    var name, email string
    if err := rows.Scan(&name, &email); err != nil {
        log.Fatalf("Scan failed: %v", err)
    }
    fmt.Printf("User: %s, Email: %sn", name, email)
}

if err := rows.Err(); err != nil {
    log.Fatalf("Rows iteration error: %v", err)
}

Ключевые моменты и альтернативы

  • Производительность: Вложенные запросы могут быть неэффективными на больших объемах данных, так как СУБД может выполнять внутренний запрос для каждой строки внешнего запроса.
  • Альтернатива (JOIN): Часто JOIN является более производительной альтернативой, так как оптимизатор запросов СУБД лучше справляется с обработкой соединений. Тот же результат можно получить так:
    SELECT u.name, u.email
    FROM users u
    JOIN orders o ON u.id = o.user_id
    WHERE o.amount > 100
    GROUP BY u.id;

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