Я предполагаю, что нет способа сделать это в одном запросе, так как INSERT
ничего не возвращает и не может использоваться в подзапросе. В том, что
интуиция верна?
Вы можете использовать Триггер и небольшую модификацию таблиц, а затем вы можете сделать это с помощью одного запроса.
Например, рассмотрим следующий
Чисто для удобства изготовления демо: -
DROP TRIGGER IF EXISTS add_group_if_not_exists;
DROP TABLE IF EXISTS contact;
DROP TABLE IF EXISTS groups;
Однократная настройка SQL: -
CREATE TABLE IF NOT EXISTS groups (id INTEGER PRIMARY KEY, group_name TEXT UNIQUE);
INSERT INTO groups VALUES(-1,'NOTASSIGNED');
CREATE TABLE IF NOT EXISTS contact (id INTEGER PRIMARY KEY, contact TEXT, group_to_use TEXT, group_reference TEXT DEFAULT -1 REFERENCES groups(id));
CREATE TRIGGER IF NOT EXISTS add_group_if_not_exists
AFTER INSERT ON contact
BEGIN
INSERT OR IGNORE INTO groups (group_name) VALUES(new.group_to_use);
UPDATE contact SET group_reference = (SELECT id FROM groups WHERE group_name = new.group_to_use), group_to_use = NULL WHERE id = new.id;
END;
SQL, который будет использоваться на постоянной основе: -
INSERT INTO contact (contact,group_to_use) VALUES
('Fred','Friends'),
('Mary','Family'),
('Ivan','Enemies'),
('Sue','Work colleagues'),
('Arthur','Fellow Rulers'),
('Amy','Work colleagues'),
('Henry','Fellow Rulers'),
('Canute','Fellow Ruler')
;
- Количество значений и фактические значения будут различаться.
SQL Просто для демонстрации результата
SELECT * FROM groups;
SELECT contact,group_name FROM contact JOIN groups ON group_reference = groups.id;
Результаты
В результате: -
1) Группы (отмечая, что группа «NOTASSIGNED» является неотъемлемой частью работы вышеупомянутого и, следовательно, добавляется изначально): -

- нужно быть осторожным в отношении ошибок вроде (Товарищ правитель вместо товарищей правителей)
- -1 , потому что это не будет автоматически генерируемое нормальное значение.
2) Контакты с соответствующей группой: -

Эффективная вставка
Скорее всего, это будет обсуждаться отсюда до бесконечности, так что я оставляю это на усмотрение ситтеров / разрушителей забора :). Однако некоторые соображения: -
- Он работает и, кажется, делает то, что хотел.
- Это немного расточительно из-за дополнительной потраченной впустую колонки.
- Он пытается свести к минимуму потери путем изменения столбца на пустую строку (NULL может быть даже более эффективным, но для некоторых это может сбить с толку)
- Очевидно, что по сравнению с альтернативами, вероятно, будут накладные расходы, незначительные (возможно, важные, если вы извлекали каждого пользователя Facebook), но если это ввод пользователя, вероятно, не имеет значения.
Какая лучшая практика здесь?
Снова заборы. :)
Примечание Надеемся, что это очевидно, но операторы DROP приведены исключительно для удобства и что все другие SQL вплоть до INSERT запускаются один раз
настроить таблицы и триггеры при подготовке к одиночной вставке
который добавляет группу при необходимости.