I would like to vertically split an existing (already filled with data).
Say my starting table ( trip
) looks like this:
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
.
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. (I would then delete the trip.person
and trip.age
column from the original table, and have the data structured as I want them.)
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.
I also thought about using an OUTPUT
clause on the INSERT
statement, but that wouldn't work either
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)
Here is an idea:
First, you insert all distinct Person
from Trip
table to Person
table:
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:
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
:
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:
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. Instead, store the birthdate and compute the age on the fly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.