2

Я хотел бы вертикально разделить уже существующие (уже заполненные данные).SQL: таблица с вертикальным разделением и создание/заполнение ключей, отношение внешних ключей

Say моей стартовой стол (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 и trip.

При копировании каждого уникального человека в таблицу person, я хочу автоматически созданный uniqueidentifier столбец в этой таблице person.pId (первичный ключ), которые будут скопированы во вновь созданный uniqueidentifier колонке trip.personid в исходной таблице и превратить это в иностранный ключ. (Я бы затем удалил столбец из исходной таблицы и имел данные, структурированные так, как они мне нужны.)

Я думал, что могу использовать триггер для этого, когда я вставляю строки человека в новую таблицу, как так:

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. 

Видимо триггер выполняет только после того, как все (! потенциально множественные) вставки были выполнены, и к тому времени запроса на вставленный больше не допускается f или мой SET.

Я тоже думал об использовании OUTPUT пункта о INSERT заявлении, но это не будет работать либо

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) 

Так мне интересно, сейчас, я буду об этом все не так? Есть ли другой способ автоматического создания ключей и отношений между двумя новыми таблицами разделения?

EDIT Желаемый результат: Таблица поездки:

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 все должно быть uniqueidentifiers, конечно)

+0

Пожалуйста, сообщите ожидаемый результат. –

+0

Я добавил таблицы, как бы хотел, чтобы они выглядели; Надеюсь, это поможет? Приветствия. – TVogt

ответ

1

Вот идея:

Во-первых, вы вносите все Person от Trip стола к 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 

Затем добавить новый столбец FK в Trip таблице PersonId, который ссылается на pId из Person таблицы:

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

Затем UPDATE новодобавленный колонке FK с от Person таблица с использованием JOIN по Person и Age:

UPDATE t 
    SET PersonId = p.pID 
FROM Trip t 
INNER JOIN Person p 
    ON p.Person = t.Person 
    AND p.Age = t.Age 

Наконец, вы можете оставить Person и Age из Trip таблицы:

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 Примечание: Вы не должны хранить Age человека. Вместо этого сохраните дату рождения и вычислите возраст на лету.

+1

Привет, это действительно работает. Я попытался сделать это одновременно, но это намного яснее и элегантнее. Что касается «age», я просто искал простой атрибут для моего примера. В таблице, на которой я действительно хочу сделать это, есть 50 или около того столбцов и 250 000 строк. Я импортировал файл csv, и теперь его нужно отсортировать по нескольким таблицам. Опять же, большое спасибо! – TVogt

 Смежные вопросы

  • Нет связанных вопросов^_^