INNER JOIN, если дочерних записей нет. Все строки левой таблицы оставляет LEFT JOIN, а поля правой заполняет NULL.">
Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗cpSpRlLft 623 of 696 menu
◀ ▶

Запись без пары в выборке в C++

Родителя без детей отбрасывает INNER JOIN, если дочерних записей нет.

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

#include <iostream> #include <sqlite3.h> int main() { sqlite3* db = nullptr; if (sqlite3_open("left_catalog.db", &db) != SQLITE_OK) { std::cerr << sqlite3_errmsg(db) << "\n"; sqlite3_close(db); return 1; } sqlite3_exec( db, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr ); sqlite3_exec( db, "CREATE TABLE IF NOT EXISTS categories (" "id INTEGER PRIMARY KEY, label TEXT NOT NULL)", nullptr, nullptr, nullptr ); sqlite3_exec( db, "CREATE TABLE IF NOT EXISTS products (" "id INTEGER PRIMARY KEY, category_id INTEGER NOT NULL, " "sku TEXT NOT NULL, " "FOREIGN KEY (category_id) REFERENCES categories (id))", nullptr, nullptr, nullptr ); sqlite3_stmt* category = nullptr; sqlite3_prepare_v2( db, "INSERT INTO categories (label) VALUES (?)", -1, &category, nullptr ); sqlite3_bind_text(category, 1, "Tools", -1, SQLITE_STATIC); sqlite3_step(category); sqlite3_reset(category); sqlite3_bind_text(category, 1, "Empty shelf", -1, SQLITE_STATIC); sqlite3_step(category); sqlite3_finalize(category); sqlite3_stmt* product = nullptr; sqlite3_prepare_v2( db, "INSERT INTO products (category_id, sku) VALUES (?, ?)", -1, &product, nullptr ); sqlite3_bind_int(product, 1, 1); sqlite3_bind_text(product, 2, "T-100", -1, SQLITE_STATIC); sqlite3_step(product); sqlite3_finalize(product); sqlite3_stmt* sel = nullptr; sqlite3_prepare_v2( db, "SELECT c.label, p.sku FROM categories c " "LEFT JOIN products p ON p.category_id = c.id " "ORDER BY c.id, p.id", -1, &sel, nullptr ); while (sqlite3_step(sel) == SQLITE_ROW) { const char* label = reinterpret_cast<const char*>( sqlite3_column_text(sel, 0) ); std::cout << label << "\n"; if (sqlite3_column_type(sel, 1) == SQLITE_NULL) { std::cout << "no sku\n"; } else { const char* sku = reinterpret_cast<const char*>( sqlite3_column_text(sel, 1) ); std::cout << sku << "\n"; } } sqlite3_finalize(sel); sqlite3_close(db); return 0; }

Строка с id 2 дает NULL в sku. Тип колонки через sqlite3_column_type подтверждает отсутствие значения:

#include <iostream> #include <sqlite3.h> int main() { sqlite3* db = nullptr; if (sqlite3_open("left_null.db", &db) != SQLITE_OK) { std::cerr << sqlite3_errmsg(db) << "\n"; sqlite3_close(db); return 1; } sqlite3_exec( db, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr ); sqlite3_exec( db, "CREATE TABLE IF NOT EXISTS categories (" "id INTEGER PRIMARY KEY, label TEXT NOT NULL)", nullptr, nullptr, nullptr ); sqlite3_exec( db, "CREATE TABLE IF NOT EXISTS products (" "id INTEGER PRIMARY KEY, category_id INTEGER NOT NULL, " "sku TEXT NOT NULL, " "FOREIGN KEY (category_id) REFERENCES categories (id))", nullptr, nullptr, nullptr ); sqlite3_stmt* category = nullptr; sqlite3_prepare_v2( db, "INSERT INTO categories (label) VALUES (?)", -1, &category, nullptr ); sqlite3_bind_text(category, 1, "Empty shelf", -1, SQLITE_STATIC); sqlite3_step(category); sqlite3_finalize(category); sqlite3_stmt* sel = nullptr; sqlite3_prepare_v2( db, "SELECT c.label, p.sku FROM categories c " "LEFT JOIN products p ON p.category_id = c.id " "WHERE c.label = 'Empty shelf'", -1, &sel, nullptr ); if (sqlite3_step(sel) == SQLITE_ROW) { bool empty = sqlite3_column_type(sel, 1) == SQLITE_NULL; std::cout << (empty ? "true" : "false") << "\n"; } sqlite3_finalize(sel); sqlite3_close(db); return 0; }

В left_catalog.db добавьте категорию "Spare" без товаров. Выведите ее метку и "no sku", если артикул пуст.

Создайте left_teams.db с таблицами teams и members. Одна команда без участников должна появиться в выводе с пустым именем участника.

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