簡體   English   中英

SQL:垂直拆分表並創建/填充鍵、外鍵關系

[英]SQL: vertically split table and create/populate keys, foreign key relationship

我想垂直拆分現有的(已填充數據)。

假設我的起始表 ( 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

我想把這張桌子分成兩張桌子,應該是這樣的,一個person一個person trip

將每個唯一的 person 復制到表person ,我希望將表person.pId (主鍵)中自動創建的uniqueidentifier列復制到原始表中新創建的uniqueidentifiertrip.personid中,並將其轉換為外部鑰匙。 (然后我會從原始表中刪除trip.persontrip.age列,並按照我想要的方式構建數據。)

當我將人員行插入新表時,我想我可以使用觸發器,如下所示:

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

但是,我明白了:

    Subquery returned more than 1 value. 
This is not permitted when the subquery follows =, !=, <, <= , >, >= 
or when the subquery is used as an expression.

顯然,觸發器僅在執行完所有(可能是多個!)插入后才執行,到那時,我的SET語句不再允許對插入的查詢。

我還考慮過在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)

所以我現在想知道,這一切都錯了嗎? 還有另一種方法可以自動創建兩個新拆分的表之間的鍵和關系嗎?

編輯所需的結果:表旅行:

  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

表人

  pId    Person       Age         
 xxxx1   Alice        21         
 xxxx2   Bob          35              
 xxxx3   Carol        29 

(當然,ID 字段應該都是唯一標識符)

這是一個想法:

首先,將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

然后,向TripPersonId添加一個新的 FK 列,該列引用Person表中的pId

ALTER TABLE Trip 
    ADD PersonId UNIQUEIDENTIFIER 
    FOREIGN KEY(PersonId) REFERENCES Person(pId)

然后,使用PersonAge上的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

最后,您可以從Trip表中刪除PersonAge

ALTER TABLE Trip DROP COLUMN Person
ALTER TABLE Trip DROP COLUMN Age

結果

pID                                  Person     Age
------------------------------------ ---------- -----------
35815766-1634-45FF-A3F6-8194B43F3F65 Alice      21
8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67 Bob        35
D0EDCEA8-3825-4693-9352-BF7A04AEFCB2 Carol      29

旅行

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

旁注:您不應該存儲此人的Age 相反,存儲生日並動態計算年齡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM