Группировка строк в SQL
Конструкция GROUP BY собирает строки с одинаковым
значением колонки в одну группу.
Агрегат считают отдельно для каждой такой группы. Сумма по коду склада для нескольких партий:
#include <iostream>
#include <sqlite3.h>
int main() {
sqlite3* db = nullptr;
if (sqlite3_open("grouped.db", &db) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
char* err = nullptr;
if (sqlite3_exec(
db,
"CREATE TABLE IF NOT EXISTS parcels ("
"id INTEGER PRIMARY KEY,"
"zone TEXT NOT NULL,"
"units INTEGER NOT NULL"
")",
nullptr,
nullptr,
&err
) != SQLITE_OK) {
std::cerr << err << "\n";
sqlite3_free(err);
sqlite3_close(db);
return 1;
}
if (sqlite3_exec(
db,
"INSERT INTO parcels (zone, units) VALUES ('A', 3)",
nullptr,
nullptr,
&err
) != SQLITE_OK) {
std::cerr << err << "\n";
sqlite3_free(err);
sqlite3_close(db);
return 1;
}
if (sqlite3_exec(
db,
"INSERT INTO parcels (zone, units) VALUES ('A', 5)",
nullptr,
nullptr,
&err
) != SQLITE_OK) {
std::cerr << err << "\n";
sqlite3_free(err);
sqlite3_close(db);
return 1;
}
if (sqlite3_exec(
db,
"INSERT INTO parcels (zone, units) VALUES ('B', 2)",
nullptr,
nullptr,
&err
) != SQLITE_OK) {
std::cerr << err << "\n";
sqlite3_free(err);
sqlite3_close(db);
return 1;
}
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(
db,
"SELECT zone, SUM(units) AS total FROM parcels "
"GROUP BY zone ORDER BY zone",
-1,
&stmt,
nullptr
) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* zone =
reinterpret_cast<const char*>(
sqlite3_column_text(stmt, 0)
);
std::cout << zone << "\n";
std::cout << sqlite3_column_int(stmt, 1) << "\n";
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
В списке SELECT без агрегата могут быть только
поля из GROUP BY. Фильтр по итогу группы
задают через HAVING, а не WHERE:
#include <iostream>
#include <sqlite3.h>
int main() {
sqlite3* db = nullptr;
if (sqlite3_open("grouped.db", &db) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
sqlite3_stmt* stmt = nullptr;
if (sqlite3_prepare_v2(
db,
"SELECT zone, SUM(units) AS total FROM parcels "
"GROUP BY zone HAVING total >= 5",
-1,
&stmt,
nullptr
) != SQLITE_OK) {
std::cerr << sqlite3_errmsg(db) << "\n";
sqlite3_close(db);
return 1;
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
const char* zone =
reinterpret_cast<const char*>(
sqlite3_column_text(stmt, 0)
);
std::cout << zone << "\n";
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
Создайте таблицу pallets в wh.db
с полями aisle и boxes, добавьте
шесть строк и выведите сумму boxes для
каждого aisle.
Оставьте только проходы, где сумма коробок не
меньше 10, и выведите их коды.