如何复制记录、修改记录并将它们添加到相同的 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 添加到原始记录的 ReverseID 列,反之亦然
所以新的 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;
但是,您可以使用纯查询获得相同的结果,而无需重复行。为什么要这样做?
- 你把浪费的 space 留给颠倒的行。
- 即使您忘记了 运行 反转并将它们插入 table.
的过程,您始终会得到最后一秒的反转行
- 如果您从 table.
中插入或删除行,则没有一致性问题
以下是您可以执行此操作的方法。
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;
请注意,不需要临时表。
我有一些问题,希望你能帮助我。 :)
我有的是这样的table:
ID Col1 Col2 ReverseID
1 Number 1 Number A
2 Number 2 Number B
3 Number 3 Number C
我要实现的是:
- 为每条带有切换列的记录创建副本,并将它们添加到原始记录中 table
- 将重复项的 ID 添加到原始记录的 ReverseID 列,反之亦然
所以新的 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;
但是,您可以使用纯查询获得相同的结果,而无需重复行。为什么要这样做?
- 你把浪费的 space 留给颠倒的行。
- 即使您忘记了 运行 反转并将它们插入 table. 的过程,您始终会得到最后一秒的反转行
- 如果您从 table. 中插入或删除行,则没有一致性问题
以下是您可以执行此操作的方法。
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;
请注意,不需要临时表。