Склейте два стола - PullRequest
0 голосов
/ 21 июля 2011

Рассмотрим две таблицы: Во-первых:

Id Data
1  asd
2  buu

и второе: UPD:

Id Data
10  ffu
11  fffuuu
10001  asd

Я хочу получить таблицу из 4 столбцов, которая выглядит следующим образом:

Id1  Data1    Id2 Data2
1     asd      10     fuu  
2     buu      11     fffuuu
-1 [any text]  10001   asd

(если номера строк не равны, давайте используем «-1» для идентификатора) Как это сделать?

Я использую sqlite3-3.7.3.

UPD2: Между таблицами нет критериев соответствия, для меня будет достаточно случайного соответствия между ними.

1 Ответ

3 голосов
/ 22 июля 2011

Предполагая, что столбцы идентификаторов уникальны и не равны NULL, вы можете «сжать» ваши таблицы следующим образом:

  1. Создание номера строки для каждой строки, которая соответствует положению строки в таблицезаказывается по уникальному идентификатору (как упомянул полищук в своем комментарии);и
  2. Имитация полного внешнего соединения с 2 левыми внешними соединениями.

Для демонстрации я использовал две таблицы с различным количеством строк:

CREATE TABLE foo (id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT);
INSERT INTO foo VALUES (NULL, 'a');
INSERT INTO foo VALUES (NULL, 'b');
INSERT INTO foo VALUES (NULL, 'c');
INSERT INTO foo VALUES (NULL, 'd');
INSERT INTO foo VALUES (NULL, 'e');
INSERT INTO foo VALUES (NULL, 'f');
INSERT INTO foo VALUES (NULL, 'g');
INSERT INTO foo VALUES (NULL, 'h');
INSERT INTO foo VALUES (NULL, 'i');
INSERT INTO foo VALUES (NULL, 'j');
DELETE FROM foo WHERE data IN ('b', 'd', 'f', 'i');

CREATE TABLE bar (id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT);
INSERT INTO bar VALUES (NULL, 'a');
INSERT INTO bar VALUES (NULL, 'b');
INSERT INTO bar VALUES (NULL, 'c');
INSERT INTO bar VALUES (NULL, 'd');
INSERT INTO bar VALUES (NULL, 'e');
INSERT INTO bar VALUES (NULL, 'f');
INSERT INTO bar VALUES (NULL, 'g');
INSERT INTO bar VALUES (NULL, 'h');
INSERT INTO bar VALUES (NULL, 'i');
INSERT INTO bar VALUES (NULL, 'j');
DELETE FROM bar WHERE data IN ('a', 'b');

Длячтобы получить более читаемый вывод, я затем запустил:

.headers on
.mode column

Затем вы можете выполнить этот оператор SQL:

SELECT COALESCE(id1, -1) AS id1, data1, 
       COALESCE(id2, -1) as id2, data2 
FROM (
    SELECT ltable.rnum AS rnum, 
           ltable.id AS id1, ltable.data AS data1, 
           rtable.id AS id2, rtable.data AS data2
    FROM
        (SElECT (SELECT COUNT(*) FROM foo 
            WHERE id <= T1.id) rnum, id, data FROM foo T1
        ) ltable
        LEFT OUTER JOIN
        (SElECT (SELECT COUNT(*) FROM bar 
            WHERE id <= T1.id) rnum, id, data FROM bar T1
        ) rtable
        ON ltable.rnum=rtable.rnum
    UNION
    SELECT rtable.rnum AS rnum, 
           ltable.id AS id1, ltable.data AS data1, 
           rtable.id AS id2, rtable.data AS data2
    FROM
        (SElECT (SELECT COUNT(*) FROM bar 
            WHERE id <= T1.id) rnum, id, data FROM bar T1
        ) rtable
        LEFT OUTER JOIN
        (SElECT (SELECT COUNT(*) FROM foo 
            WHERE id <= T1.id) rnum, id, data FROM foo T1
        ) ltable
        ON ltable.rnum=rtable.rnum)
ORDER BY rnum

, который дает вам:

id1         data1       id2         data2     
----------  ----------  ----------  ----------
1           a           3           c         
3           c           4           d         
5           e           5           e         
7           g           6           f         
8           h           7           g         
10          j           8           h         
-1                      9           i         
-1                      10          j    

Thisработает «в обе стороны», например, если вы инвертируете две таблицы (foo и bar), вы получите:

id1         data1       id2         data2     
----------  ----------  ----------  ----------
3           c           1           a         
4           d           3           c         
5           e           5           e         
6           f           7           g         
7           g           8           h         
8           h           10          j         
9           i           -1                    
10          j           -1                  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...