Начальные данные с использованием оператора слияния, включая данные из внешней таблицы - PullRequest
1 голос
/ 15 октября 2019

Мне предоставлен файл excel с данными, которые я должен объединить в базу данных. Исходя из этих данных, я объединяю строку в следующем формате:

('Maastricht','demolitionCost',2.64,86.64,26.12,'€/m²','EUR',1),

'Maastricht' - это название города, которое мне нужно добавить во внешнюю таблицу во время вставки. Вот сценарий, который я придумал:

MERGE INTO [Cost] AS Target
USING (VALUES
    ('Maastricht','demolitionCost',2.64,86.64,26.12,'€/m²','EUR',1),
    ('Maastricht','buildCost',81.86,1863.54,679.28,'€/m²','EUR',1),
    ('Maastricht','refurbishmentCost',81.86,1863.54,679.28,'€/m²','EUR',1),
    ('Amsterdam','demolitionCost',2.77,90.97,27.42,'€/m²','EUR',1),
    ('Amsterdam','buildCost',85.93,1956.72,713.24,'€/m²','EUR',1),
    ('Amsterdam','refurbishmentCost',85.93,1956.72,713.24,'€/m²','EUR',1)
)
AS Source (City, [Name], MinValue, MaxValue, MedianValue, MeasurementUnit, CurrencyCode, IsActive)
ON Target.[Name] = Source.[Name] AND 
   Target.[MinValue] = Source.[MinValue] AND
   Target.[MaxValue] = Source.[MaxValue] AND
   Target.[MedianValue] = Source.[MedianValue] AND
   Target.[MeasurementUnit] = Source.[MeasurementUnit] AND
   Target.[CurrencyCode] = Source.[CurrencyCode]

WHEN NOT MATCHED BY TARGET THEN
INSERT (LocationId, [Name],[MinValue], [MaxValue], [MedianValue], [MeasurementUnit], [CurrencyCode], [CreatedDate], [ModifiedDate], [IsActive])
VALUES (
    (Select Top(1) Id from location loc where loc.City = City), 
    [Name], 
    [MinValue], 
    [MaxValue], 
    [MedianValue],
    [MeasurementUnit],
    [CurrencyCode],
    GetDate(),
    GetDate(),
    IsActive);

GO

Чтобы заменить название города фактическим внешним ключом, я попытался просто сделать выбор из таблицы местоположений, которая, к сожалению, дает мне только первоеЕсли он действительно находит, что приводит к неправильным отношениям.

Как правильно искать внешний ключ для названия города, поэтому он вставляет правильное значение во время вставки?

Ответы [ 2 ]

3 голосов
/ 15 октября 2019

Вы можете присоединить таблицу местоположений к таким значениям, как это:

MERGE INTO [Cost] AS Target
USING 
    (
        SELECT Id, [Name], MinValue, MaxValue, MedianValue, MeasurementUnit, CurrencyCode, IsActive
        FROM location AS loc 
        JOIN (VALUES
                ('Maastricht','demolitionCost',2.64,86.64,26.12,'€/m²','EUR',1),
                ('Maastricht','buildCost',81.86,1863.54,679.28,'€/m²','EUR',1),
                ('Maastricht','refurbishmentCost',81.86,1863.54,679.28,'€/m²','EUR',1),
                ('Amsterdam','demolitionCost',2.77,90.97,27.42,'€/m²','EUR',1),
                ('Amsterdam','buildCost',85.93,1956.72,713.24,'€/m²','EUR',1),
                ('Amsterdam','refurbishmentCost',85.93,1956.72,713.24,'€/m²','EUR',1)
             ) AS  V(City, [Name], MinValue, MaxValue, MedianValue, MeasurementUnit, CurrencyCode, IsActive)
            ON loc.City = V.City
)
AS Source 
ON Target.[Name] = Source.[Name] AND 
   Target.[MinValue] = Source.[MinValue] AND
   Target.[MaxValue] = Source.[MaxValue] AND
   Target.[MedianValue] = Source.[MedianValue] AND
   Target.[MeasurementUnit] = Source.[MeasurementUnit] AND
   Target.[CurrencyCode] = Source.[CurrencyCode]

WHEN NOT MATCHED BY TARGET THEN
INSERT (LocationId, [Name],[MinValue], [MaxValue], [MedianValue], [MeasurementUnit], [CurrencyCode], [CreatedDate], [ModifiedDate], [IsActive])
VALUES (
    Id, 
    [Name], 
    [MinValue], 
    [MaxValue], 
    [MedianValue],
    [MeasurementUnit],
    [CurrencyCode],
    GetDate(),
    GetDate(),
    IsActive
);

GO
2 голосов
/ 15 октября 2019

Измените свой [Источник], чтобы присоединиться к таблице местоположений там

DECLARE @Location table (Id INT, City NVARCHAR(100))
INSERT INTO @Location (Id, City) VALUES (1, 'Maastricht'), (2, 'Amsterdam')

;with cteSource
AS(
    select [Source].*, LocationId = Loc.Id
    from (VALUES
        ('Maastricht','demolitionCost',2.64,86.64,26.12,'€/m²','EUR',1),
        ('Maastricht','buildCost',81.86,1863.54,679.28,'€/m²','EUR',1),
        ('Maastricht','refurbishmentCost',81.86,1863.54,679.28,'€/m²','EUR',1),
        ('Amsterdam','demolitionCost',2.77,90.97,27.42,'€/m²','EUR',1),
        ('Amsterdam','buildCost',85.93,1956.72,713.24,'€/m²','EUR',1),
        ('Amsterdam','refurbishmentCost',85.93,1956.72,713.24,'€/m²','EUR',1)
    ) AS [Source] (City, [Name], MinValue, MaxValue, MedianValue, MeasurementUnit, CurrencyCode, IsActive)
    INNER JOIN @Location LOC ON LOC.City = [Source].City
)
MERGE INTO [Cost] AS [Target]
USING cteSource AS [SOURCE]
ON Target.[Name] = Source.[Name] AND 
   Target.[MinValue] = Source.[MinValue] AND
   Target.[MaxValue] = Source.[MaxValue] AND
   Target.[MedianValue] = Source.[MedianValue] AND
   Target.[MeasurementUnit] = Source.[MeasurementUnit] AND
   Target.[CurrencyCode] = Source.[CurrencyCode]

WHEN NOT MATCHED BY TARGET THEN
INSERT (LocationId, [Name],[MinValue], [MaxValue], [MedianValue], [MeasurementUnit], [CurrencyCode], [CreatedDate], [ModifiedDate], [IsActive])
VALUES (
    LocationId , 
    [Name], 
    [MinValue], 
    [MaxValue], 
    [MedianValue],
    [MeasurementUnit],
    [CurrencyCode],
    GetDate(),
    GetDate(),
    IsActive
);
...