2017-02-23 99 views
1

У меня есть база данных с тремя таблицами «контакты», «имена» и «контакты».SQLite insert select result несколько раз

create table contacts(id integer, gid integer, sid integer); 
create table names(id integer primary key, name text); 
create table contact_names(fullname text); 

insert into names(name) values ('Eberhard'); 
insert into names(name) values ('Esche'); 

insert into contacts values(1, (select id from names where name='Eberhard'), (select id from names where name='Esche')); 

Теперь я хочу, чтобы вставить пару «заданное имя + фамилию» дважды, один раз как «данное имя + фамилия» и один раз как «фамилию + имя данного». То, что я в настоящее время является Постулаты так, чтобы генерировать эти имена:

SELECT gTable.name || ' ' || sTable.name AS name1, sTable.name || ' ' || gTable.name AS name2 FROM 
(
    SELECT name FROM names WHERE id=2 
) AS gTable, 
(
    SELECT name FROM names WHERE id=1 
) AS sTable; 

То, что я не в состоянии выполнить, чтобы вставить эти имена теперь таблицы, используя что-то «contact_names», как это:

INSERT INTO contact_names VALUES (name1), (name2) WITH 
SELECT gTable.name || ' ' || sTable.name AS name1, sTable.name || ' ' || gTable.name AS name2 FROM 
(
    SELECT name FROM names WHERE id=2 
) AS gTable, 
(
    SELECT name FROM names WHERE id=1 
) AS sTable; 

В результате таблица «contact_names» должна содержать две записи (строки) «Esche Eberhard» и «Eberhard Esche». Кто-нибудь знает, как это достичь? Конечно, я мог бы сделать инструкцию select дважды, но я бы предпочел сделать это с помощью одного выбора.

BR, Удо

PS: Может быть, это полезно, чтобы объяснить, почему я хочу, чтобы сделать это. Инструкция INSERT для «contact_names» должна выполняться триггером, который вызывается при удалении записей из «контактов». Если удалить строку для экземпляра с

DELETE FROM contacts WHERE id=1; 

затем два имени комбинация этого контакта должна быть вставлена ​​в «contact_names» (для дальнейшей обработки этих имен). После обработки удаленных имен таблица будет очищена регулярно.

+0

Это кажется очень странным требованием. Похоже, что имя и фамилия хранятся в разных _records_ в таблице «names», но вы хотите ее развернуть, а также дублировать первую/последнюю комбинацию. –

ответ

0

У вас есть одна строка с двумя столбцами, но вы хотите две строки с одним столбцом.

В общем случае, это может быть сделано с помощью common table expression и compound query:

WITH TwoColumns(a, b) AS (
    SELECT a, b FROM ...  -- the original two-column query 
) 
INSERT INTO ...(x) 
SELECT a FROM TwoColumns 
UNION ALL 
SELECT b FROM TwoColumns; 

В этом случае нам не нужно так много подзапросов и может упростить немного:

WITH gs(gName, sName) AS (
    SELECT g.name, 
      s.name 
    FROM names AS g, 
     names AS s 
    WHERE g.id = 2 
     AND s.id = 1 
) 
INSERT INTO contact_names(fullname) 
SELECT gName || ' ' || sName FROM gs 
UNION ALL 
SELECT sName || ' ' || gName FROM gs; 
+0

Спасибо за это решение, оно решило проблему. Я просто хочу упомянуть, что sqlite3 версии 3.8.2 не понимает этот синтаксис, я всегда получаю сообщение об ошибке, что в заявлении WITH есть проблема. Использование sqlite3 версии 3.11.0 на другой машине, это утверждение работает, поэтому, очевидно, что старая версия не поддерживает этот тип WITH. – drhuh