Запись без пары в выборке в Java
INNER JOIN отбрасывает родителя, у которого
нет ни одной дочерней записи. LEFT JOIN
оставляет все строки левой таблицы, а поля правой
заполняет NULL, если пара не найдена.
Категория без товаров всё равно попадает в результат, а имя товара читают с проверкой на пустоту:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:left_catalog.db")) {
connection.createStatement().execute(
"PRAGMA foreign_keys = ON"
);
try (Statement statement = connection.createStatement()) {
statement.execute(
"""
CREATE TABLE IF NOT EXISTS categories (
id INTEGER PRIMARY KEY,
label TEXT NOT NULL
)
"""
);
statement.execute(
"""
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)
)
"""
);
}
PreparedStatement category = connection.prepareStatement(
"INSERT INTO categories (label) VALUES (?)"
);
category.setString(1, "Tools");
category.executeUpdate();
category.setString(1, "Empty shelf");
category.executeUpdate();
PreparedStatement product = connection.prepareStatement(
"""
INSERT INTO products (category_id, sku)
VALUES (?, ?)
"""
);
product.setInt(1, 1);
product.setString(2, "T-100");
product.executeUpdate();
try (Statement statement = connection.createStatement()) {
ResultSet result = statement.executeQuery(
"""
SELECT c.label, p.sku
FROM categories c
LEFT JOIN products p
ON p.category_id = c.id
ORDER BY c.id, p.id
"""
);
while (result.next()) {
System.out.println(result.getString("label"));
String sku = result.getString("sku");
System.out.println(sku != null ? sku : "no sku");
}
}
}
}
}
Строка с id 2 даёт null
в sku. Метод wasNull после
чтения подтверждает отсутствие значения:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:left_null.db")) {
connection.createStatement().execute(
"PRAGMA foreign_keys = ON"
);
try (Statement statement = connection.createStatement()) {
statement.execute(
"""
CREATE TABLE IF NOT EXISTS categories (
id INTEGER PRIMARY KEY,
label TEXT NOT NULL
)
"""
);
statement.execute(
"""
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)
)
"""
);
}
PreparedStatement category = connection.prepareStatement(
"INSERT INTO categories (label) VALUES (?)"
);
category.setString(1, "Empty shelf");
category.executeUpdate();
try (Statement statement = connection.createStatement()) {
ResultSet result = statement.executeQuery(
"""
SELECT c.label, p.sku
FROM categories c
LEFT JOIN products p
ON p.category_id = c.id
WHERE c.label = 'Empty shelf'
"""
);
if (result.next()) {
result.getString("sku");
System.out.println(result.wasNull());
}
}
}
}
}
В left_catalog.db добавьте категорию
"Spare" без товаров. Выведите её
метку и "no sku", если артикул пуст.
Создайте left_teams.db с таблицами
teams и members. Одна команда
без участников должна появиться в выводе с
пустым именем участника.