Запись без пары в выборке в Kotlin
INNER JOIN отбрасывает родителя, у которого
нет ни одной дочерней записи. LEFT JOIN
оставляет все строки левой таблицы, а поля правой
заполняет NULL, если пара не найдена.
Категория без товаров всё равно попадает в результат, а имя товара читают с проверкой на пустоту:
import java.sql.DriverManager
fun main() {
DriverManager.getConnection("jdbc:sqlite:left_catalog.db")
.use { connection ->
connection.createStatement().execute(
"PRAGMA foreign_keys = ON"
)
connection.createStatement().use { statement ->
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)
)
"""
)
}
val category = connection.prepareStatement(
"INSERT INTO categories (label) VALUES (?)"
)
category.setString(1, "Tools")
category.executeUpdate()
category.setString(1, "Empty shelf")
category.executeUpdate()
val product = connection.prepareStatement(
"""
INSERT INTO products (category_id, sku)
VALUES (?, ?)
"""
)
product.setInt(1, 1)
product.setString(2, "T-100")
product.executeUpdate()
connection.createStatement().use { statement ->
val 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()) {
println(result.getString("label"))
val sku = result.getString("sku")
println(sku ?: "no sku")
}
}
}
}
Строка с id 2 даёт null
в sku. Метод wasNull после
чтения подтверждает отсутствие значения:
import java.sql.DriverManager
fun main() {
DriverManager.getConnection("jdbc:sqlite:left_null.db")
.use { connection ->
connection.createStatement().execute(
"PRAGMA foreign_keys = ON"
)
connection.createStatement().use { statement ->
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)
)
"""
)
}
val category = connection.prepareStatement(
"INSERT INTO categories (label) VALUES (?)"
)
category.setString(1, "Empty shelf")
category.executeUpdate()
connection.createStatement().use { statement ->
val 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")
println(result.wasNull())
}
}
}
}
В left_catalog.db добавьте категорию
"Spare" без товаров. Выведите её
метку и "no sku", если артикул пуст.
Создайте left_teams.db с таблицами
teams и members. Одна команда
без участников должна появиться в выводе с
пустым именем участника.