如何复制记录、修改记录并将它们添加到相同的 table

How to duplicate records, modify and add them to same table

我有一些问题,希望你能帮助我。 :)

我有的是这样的table:

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

我要实现的是:

所以新的 table 应该是这样的:

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

到目前为止我所做的是使用临时 table:

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

在这个示例代码中,我使用了辅助 table 只是为了确保我不会破坏原始数据记录。

我想我可以跳过 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 知识很低,我几乎可以肯定,这不是最简单的做事方式,所以我希望你们能启发我并引导我找到更优雅的解决方案。

提前致谢!

br 捷运

编辑:

我试图说明我最初的问题,所以这篇文章很长。 ;)

.

首先:我的前端不允许任何SQL语句,我必须关注classes、属性、关系。

第一个根本原因: class B (B1, B2, B3, ...) 的实例在 class 关系中链接在一起,这些是相同 class 的多对多关系。我的前端不允许加入 tables,所以这是一个解决方法。

声明一个用户添加了一个关系,其中 B1 作为第一方(我刚刚称之为 'left'),B2 作为第二方(右):

从 B1 导航,将出现两个关系(FK_Left、FK_Right),但其中只有一个包含值(假设为 FK_Left)。

从 B2 开始导航,该值将仅列在另一个关系中 (FK_Right)。 所以从用户端来说,显示的总是两种关系,但要看记录是怎么录入的,是否能找到relation_left或relation_right后面的数据。 那是没有实际可用性的。

如果我有所有记录,反之亦然,我可以只隐藏其中一个关系,用户可以看到 一个 关系背后的所有信息,无论它是如何输入的。

第二个根本原因: 前端提供一些矩阵视图,它获取关系 class 作为输入,并在列中显示左伙伴,在行中显示右伙伴。

假设我想在列中查看 A 的所有实例,在行中查看它们的伙伴,这只有在有关 A 实例的所有关系都以相同方式输入的情况下才有可能,例如所有 A 实例作为左伙伴。

矩阵视图可以根据行和列自由过滤,所以如果我有重复关系,我可以过滤行和列中的任何合作伙伴。

抱歉,文字很长,我希望这能让我的情况更清楚一些。

这种事情的诀窍是从获取所需数据的 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 的 GUI 执行此操作,请不要忘记 DROP TABLE #tmp;

但是,您可以使用纯查询获得相同的结果,而无需重复行。为什么要这样做?

  1. 你把浪费的 space 留给颠倒的行。
  2. 即使您忘记了 运行 反转并将它们插入 table.
  3. 的过程,您始终会得到最后一秒的反转行
  4. 如果您从 table.
  5. 中插入或删除行,则没有一致性问题

以下是您可以执行此操作的方法。

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

您甚至可以将其制作成一个视图并像 table 一样使用它。

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'等等

我建议只使用视图,而不是尝试创建和维护相同数据的两个副本。然后你只是 select 从视图而不是基础 table.

create view MyReversedDataView as

select ID
    , Col1
    , Col2
from MyTable

UNION ALL

select ID
    , Col2
    , Col1
from MyTable

让我假设 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

这会插入新的 ids,右边 reverseid。现在我们必须更新以前的值:

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

请注意,不需要临时表。