Как добавить столбец данных в уже заполненную таблицу с помощью SQL?

#sql #sqlite

Вопрос:

Я пытаюсь создать своего рода мусорное ведро. Когда я удаляю столбец из таблицы, я помещаю все данные из него в специальную таблицу, называемую bin. Позже я хочу иметь возможность восстановить этот столбец и добавить его в существующую таблицу со случайными данными и произвольного размера.

Пример:

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

               Таблица                                           1 бункер

 | columnA | columnB |    | origin  | columnC | columnD |
| ------- | ------- |    | ------- | ------- | ------- |
|   aa    |   10    |    | columnD |   NULL  |    a    |
|   bb    |   20    |    | columnD |   NULL  |    s    |
|   cc    |   30    |    | columnD |   NULL  |    d    |
                         | columnD |   NULL  |    f    |
                         | columnC |   100   |   NULL  |
                         | columnC |   200   |   NULL  |
 

Теперь я хочу добавить столбец, например ColumnC или ColumnD, из таблицы bin в таблицу 1, как это:

 | columnA | columnB | columnC |
| ------- | ------- | ------- |
|    aa   |    10   |   100   |
|    bb   |    20   |   200   |
|    cc   |    30   |   NULL  |


| columnA | columnB | columnD |
| ------- | ------- | ------- |
|    aa   |    10   |    a    |
|    bb   |    20   |    s    |
|    cc   |    30   |    d    |
|   NULL  |   NULL  |    f    |


| columnA | columnB | columnC | columnD |
| ------- | ------- | ------- | ------- |
|    aa   |    10   |   100   |    a    |
|    bb   |    20   |   200   |    s    |
|    cc   |    30   |   NULL  |    d    |
|   NULL  |   NULL  |   NULL  |    f    |
 

Я использую Python и Sqlite 3.31.1, хотя я открыт для изменения версии, которую я использую, так как некоторые люди предположили, что эта версия не допускает операций объединения, так что пусть это не будет помехой.

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

 SELECT columnC
FROM bin
WHERE origin='columnC'
 

Но я не знаю, как вставить этот столбец, начиная с его первой записи, в другую таблицу, а остальные заполнить пустыми записями.

Комментарии:

1. Почему в столбце b меняются значения в третьей строке?

2. Какова ваша версия SQLite?

3. Как бы вы определили, что значение 100 в столбце должно сопровождаться aa в столбце

4. В основном только по номеру строки. Я хочу заполнить столбец, который я получаю из таблицы bin по порядку, в новый столбец в другой таблице.

5. @Obnidem Меня смущает тот факт, что ваш вопрос имеет два голоса «против» и ни одного голоса «за». Мне это кажется разумным вопросом, и, по-видимому, многие в сообществе согласны с этим, поскольку люди вступают в разговор с пояснительными комментариями и ответами. Я собираюсь поднять ваш вопрос, и я надеюсь, что ответчики и другие тоже это сделают. Добро пожаловать в сообщество.

Ответ №1:

Один из способов определить, из какой строки bin вы выберете значение columnC для обновления каждой строки table1 , — это использовать 2 коррелированных подзапроса, которые подсчитывают количество строк в каждой таблице с rowid меньшим, чем текущее rowid :

 UPDATE table1 AS t1
SET columnC = (
  SELECT b1.columnC
  FROM bin AS b1 
  WHERE (SELECT COUNT(*) FROM bin b2 WHERE b2.rowid < b1.rowid) =
        (SELECT COUNT(*) FROM table1 t2 WHERE t2.rowid < t1.rowid)
) 
 

Это решение может быть не самым эффективным для большого набора данных, но используемая вами версия SQLite не поддерживает объединения, которые будут работать лучше.

Смотрите демонстрацию.

Комментарии:

1. Это близко к истине, но работает не совсем так, как задумывалось. Я добавил еще два примера, чтобы еще больше проиллюстрировать, что я хочу сделать.

2. @Obnidem этот запрос отвечает на вопрос, как вы его опубликовали, если у вас есть новое требование, вы можете задать новый вопрос.

Ответ №2:

Я придумал решение, которое требует полного внешнего соединения, которое недоступно в sqlite, но может быть смоделировано с помощью двух последовательных левых соединений и объединения всех.

Полное Внешнее Соединение:

 SELECT A.columnA, A.columnB, B.columnC
FROM
(SELECT columnA, columnB, row_number() OVER (ORDER BY (SELECT 0)) 
AS rc FROM table1)A
FULL OUTER JOIN
(SELECT columnC, row_number() OVER (ORDER BY (SELECT 0)) 
AS rc FROM (SELECT columnC FROM bin WHERE origin='columnC'))B
ON A.rc = B.rc
 

Два Левых Объединения и Объединение Всех:

 SELECT A.columnA, A.columnB, B.columnC
FROM
(SELECT columnA, columnB, row_number() OVER (ORDER BY (SELECT 0)) 
AS rc FROM table1)A
LEFT JOIN
(SELECT columnC, row_number() OVER (ORDER BY (SELECT 0)) 
AS rc FROM (SELECT columnC FROM bin WHERE origin='columnC'))B
ON A.rc = B.rc
UNION ALL
SELECT A.columnA, A.columnB, B.columnC
FROM
(SELECT columnC, row_number() OVER (ORDER BY (SELECT 0)) 
AS rc FROM (SELECT columnC FROM bin WHERE origin='columnC'))B
LEFT JOIN
(SELECT columnA, columnB, row_number() OVER (ORDER BY (SELECT 0)) 
AS rc FROM table1)A
ON A.rc = B.rc
WHERE A.rc IS NULL;
 

Смотрите Демонстрацию.