Как дублировать записи, изменять и добавлять их в одну таблицу - PullRequest
2 голосов
/ 15 апреля 2019

У меня есть вопрос, и надеюсь, вы поможете мне. :)

У меня есть такая таблица:

ID  Col1        Col2        ReverseID
1   Number 1    Number A    
2   Number 2    Number B    
3   Number 3    Number C    

Чего я хочу добиться:

  • Создать дубликаты каждой записи с переключенными столбцами и добавить их в исходную таблицу
  • Добавить идентификатор дубликата в столбец ReverseID исходной записи и наоборот

Итак, новая таблица должна выглядеть так:

ID  Col1        Col2        ReverseID
1   Number 1    Number A    4
2   Number 2    Number B    5
3   Number 3    Number C    6
4   Number A    Number 1    1
5   Number B    Number 2    2
6   Number C    Number 3    3

То, что я до сих пор делал, работало с временной таблицей:

SELECT * INTO #tbl
FROM myTable

UPDATE #tbl
SET Col1 = Col2,
    Col2 = Col1,
    ReverseID = ID

INSERT INTO DUPLICATEtable(
        Col1,
        Col2,
        ReverseID
)

SELECT Col1,
       Col2,
       ReverseID
FROM #tbl

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

Я думаю, что мог бы пропустить часть SET и изменить столбцы в последнем операторе SELECT, чтобы добиться того же, но я не уверен.

Так или иначе - с этим я заканчиваю в:

ID  Col1        Col2        ReverseID
1   Number 1    Number A    
2   Number 2    Number B    
3   Number 3    Number C    
4   Number A    Number 1    1
5   Number B    Number 2    2
6   Number C    Number 3    3

Таким образом, остается вопрос: как правильно добавить ReverseID в исходные записи?

Поскольку мои знания SQL довольно низки, я почти уверен, что это не самый простой способ сделать что-то, поэтому я надеюсь, что вы, ребята и девушки, сможете просветить меня и привести меня к более элегантному решению.

Заранее спасибо!

ш MRT

Edit:

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

ED .

Прежде всего: мой веб-интерфейс не допускает никаких операторов SQL, я должен сосредоточиться на классах, атрибутах, отношениях.

Первая причина: Экземпляры класса B (B1, B2, B3, ...) связаны между собой в классе Relation, это отношения «многие ко многим» одного и того же класса. Мой интерфейс не позволяет объединять таблицы, так что это обходной путь.

Заявление о том, что пользователь добавляет отношение с B1 в качестве первой стороны (я только что назвал его «слева») и B2 в качестве второй стороны (справа):

При переходе от B1 будут отображаться два отношения (FK_Left, FK_Right), но только одно из них будет содержать значение (скажем, FK_Left).

При переходе от B2 значение будет указано только в другом отношении (FK_Right). Таким образом, на стороне пользователя всегда отображаются два отношения, но это зависит от того, как была введена запись, если можно найти данные за отношением_теллоу или отношением_право. Это практически невозможно.

Если у меня были все записи с обратными партнерами, я могу просто скрыть одно из отношений, и пользователь увидит всю информацию, стоящую за одним отношением, независимо от того, как оно было введено.

Вторая основная причина: Интерфейс предоставляет некоторое матричное представление, которое получает класс отношений в качестве входных данных и отображает левых партнеров в столбцах и правых партнеров в строках.

Допустим, я хочу видеть все экземпляры A в столбцах и их партнеров в строках, это возможно только в том случае, если все отношения, относящиеся к экземплярам A, вводятся одинаково, например, все экземпляры A в качестве левого партнера.

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

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

Ответы [ 3 ]

1 голос
/ 15 апреля 2019

Я бы предложил просто использовать представление вместо того, чтобы пытаться создавать и поддерживать две копии одних и тех же данных. Тогда вы просто выбираете из представления вместо базовой таблицы.

create view MyReversedDataView as

select ID
    , Col1
    , Col2
from MyTable

UNION ALL

select ID
    , Col2
    , Col1
from MyTable
1 голос
/ 15 апреля 2019

Позвольте мне предположить, что столбец id автоматически увеличивается. Затем вы можете сделать это в два этапа:

insert into myTable (Col1, Col2, reverseid)
    select col2, col1, id
    from myTable t
    order by id;  -- ensures that they go in in the right order

Вставляет новые идентификаторы с правом reverseid. Теперь мы должны обновить предыдущие значения:

update t
    set reverseid = tr.id
    from myTable t join
         myTable tr
         on tr.reverseid = t.id;

Обратите внимание, что временные таблицы не нужны.

1 голос
/ 15 апреля 2019

Хитрость такого рода вещей заключается в том, чтобы начать с SELECT, который получает необходимые данные.В этом случае вам нужен набор результатов с Col1, Col2, reverseid.

SELECT Col2 Col1, Col1 Col1, ID reverseid
  INTO #tmp   FROM myTable;

Убедитесь, что это правильно - значения столбцов поменялись местами и т. Д.

Затем сделайте следующее:

INSERT INTO myTable (Col1, col2, reverseid)
SELECT Col1, Col2, reverseid FROM #tmp;

Если вы делаете это из графического интерфейса, такого как ssms, не забудьте DROP TABLE #tmp;

НО, вы можете получить тот же результат с помощью чистого запроса, без дублирования строк.Почему это так?

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

Вот как вы можете это сделать.

 SELECT Col1, Col2, null reverseid FROM myTable
  UNION ALL
 SELECT Col2 Col1, Col1 Col2, ID reverseid FROM myTable;

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

CREATE VIEW myTableWithReversals AS
SELECT Col1, Col2, null reverseid FROM myTable
 UNION ALL
SELECT Col2 Col1, Col1 Col2, ID reverseid FROM myTable;

Тогда вы можете сказать SELECT * FROM myTableWithReversals WHERE Col1 = 'value' и т. Д.

...