[英]SQL: vertically split table and create/populate keys, foreign key relationship
I would like to vertically split an existing (already filled with data).我想垂直拆分现有的(已填充数据)。
Say my starting table ( trip
) looks like this:假设我的起始表 ( trip
) 如下所示:
ID Person Age Trip_to Date
... Alice 21 Los Angeles 2015-04-01
... Bob 35 New York 2015-03-15
... Bob 35 Chicago 2015-03-20
... Bob 35 San Francisco 2015-03-29
... Carol 29 Miami 2015-03-30
... Carol 29 Boston 2015-04-05
I would like to split this table into two tables, as it should be, one each for person
and trip
.我想把这张桌子分成两张桌子,应该是这样的,一个person
一个person
trip
。
When copying each unique person into a table person
, I want the automatically created uniqueidentifier
column in that table person.pId
(the primary key) to be copied into a newly created uniqueidentifier
column trip.personid
in the original table and turn that into a foreign key.将每个唯一的 person 复制到表person
,我希望将表person.pId
(主键)中自动创建的uniqueidentifier
列复制到原始表中新创建的uniqueidentifier
列trip.personid
中,并将其转换为外部钥匙。 (I would then delete the trip.person
and trip.age
column from the original table, and have the data structured as I want them.) (然后我会从原始表中删除trip.person
和trip.age
列,并按照我想要的方式构建数据。)
I thought I could use a trigger for that when I insert the person rows into the new table, like so:当我将人员行插入新表时,我想我可以使用触发器,如下所示:
CREATE TRIGGER tr_person
on person
after INSERT
as
begin
UPDATE Trip
SET personId=(SELECT i.pId from inserted i)
WHERE person=(SELECT i.person from inserted i) and age=(SELECT i.age from inserted i)
END
However, I get this:但是,我明白了:
Subquery returned more than 1 value.
This is not permitted when the subquery follows =, !=, <, <= , >, >=
or when the subquery is used as an expression.
Apparently the trigger only executes after all (potentially multiple!) inserts have been carried out, and by that time a query on inserted is no longer allowed for my SET
statement.显然,触发器仅在执行完所有(可能是多个!)插入后才执行,到那时,我的SET
语句不再允许对插入的查询。
I also thought about using an OUTPUT
clause on the INSERT
statement, but that wouldn't work either我还考虑过在INSERT
语句上使用OUTPUT
子句,但这也不起作用
Insert into person (Driver, Age)
OUTPUT inserted.pId INTO trip.personId WHERE trip.person=inserted.person AND trip.Age=inserted.Age
(Select DISTINCT Person, Age FROM Trip)
So I am wondering now, am going about this all wrong?所以我现在想知道,这一切都错了吗? Is there another way to automagically create the keys and relationships between the two newly split tables?还有另一种方法可以自动创建两个新拆分的表之间的键和关系吗?
EDIT Desired result: Table trip:编辑所需的结果:表旅行:
ID Trip_to Date PersonId
... Los Angeles 2015-04-01 xxxx1
... New York 2015-03-15 xxxx2
... Chicago 2015-03-20 xxxx2
... San Francisco 2015-03-29 xxxx2
... Miami 2015-03-30 xxxx3
... Boston 2015-04-05 xxxx3
Table person表人
pId Person Age
xxxx1 Alice 21
xxxx2 Bob 35
xxxx3 Carol 29
(The ID fields should all be uniqueidentifiers, of course) (当然,ID 字段应该都是唯一标识符)
Here is an idea:这是一个想法:
First, you insert all distinct Person
from Trip
table to Person
table:首先,将Trip
表中所有不同的Person
插入到Person
表中:
CREATE TABLE Person(
pID UNIQUEIDENTIFIER PRIMARY KEY,
Person VARCHAR(10),
Age INT
)
INSERT INTO Person
SELECT
NEWID(), Person, Age
FROM(
SELECT DISTINCT Person, Age FROM Trip
)t
Then, add a new FK column to Trip
table PersonId
which references pId
from the Person
table:然后,向Trip
表PersonId
添加一个新的 FK 列,该列引用Person
表中的pId
:
ALTER TABLE Trip
ADD PersonId UNIQUEIDENTIFIER
FOREIGN KEY(PersonId) REFERENCES Person(pId)
Then, UPDATE
the newly added FK column with values from Person
table using a JOIN
on Person
and Age
:然后,使用Person
和Age
上的JOIN
使用Person
表中的值UPDATE
新添加的 FK 列:
UPDATE t
SET PersonId = p.pID
FROM Trip t
INNER JOIN Person p
ON p.Person = t.Person
AND p.Age = t.Age
Finally, you can drop Person
and Age
from Trip
table:最后,您可以从Trip
表中删除Person
和Age
:
ALTER TABLE Trip DROP COLUMN Person
ALTER TABLE Trip DROP COLUMN Age
Person人
pID Person Age
------------------------------------ ---------- -----------
35815766-1634-45FF-A3F6-8194B43F3F65 Alice 21
8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67 Bob 35
D0EDCEA8-3825-4693-9352-BF7A04AEFCB2 Carol 29
Trip旅行
ID Trip_to Date PersonId
------------------------------------ -------------------- ---------- ------------------------------------
77357A57-FAAE-43DE-923E-219038B8641E Los Angeles 2015-04-01 35815766-1634-45FF-A3F6-8194B43F3F65
C1B64E81-D30A-46A9-A868-1D92C4B64B8C New York 2015-03-15 8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67
21F3614A-8E76-4A64-8A0B-815D5343FC26 Chicago 2015-03-20 8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67
E1DB1926-4268-4BFA-B5E0-DA603DA8E1B7 San Francisco 2015-03-29 8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67
F50E45E6-E689-444B-96C1-F936CA6F3D2A Miami 2015-03-30 D0EDCEA8-3825-4693-9352-BF7A04AEFCB2
C2FA7073-79D7-42E8-B2C8-6EEDBC374002 Boston 2015-04-05 D0EDCEA8-3825-4693-9352-BF7A04AEFCB2
Side note: You should not be storing the Age
of the person.旁注:您不应该存储此人的Age
。 Instead, store the birthdate and compute the age on the fly.相反,存储生日并动态计算年龄。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.