2012-10-22 8 views
0

У меня есть классическая схема person person -> person. Так, например: person (PK) < - person_attribute (FK)sql server обновляет множество столбцов с помощью выбора из объединения переменной таблицы и таблицы db.

Что мне нужно - это запрос, чтобы получить один ряд, где человек соединяется с ее атрибутами. Например, чтобы преобразовать:

Person: 
{ ID = 123456, Name = 'John Smith', Age = 25 } 
Attributes: 
1) { PersonID = 123456, AttributeTypeID = 'Height', AttributeValue = '6'6'''} 
2) { PersonID = 123456, AttributeTypeID = 'Weight', AttributeValue = '220lbs'} 
3) { PersonID = 123456, AttributeTypeID = 'EyeColor', AttributeValue = 'Blue'} 

To:

PersonWithAttributes 
{ 
ID = 123456, Name = 'John Smith', Age = 25, Height = '6'6''', Weight = '220lbs', EyeColor = 'Blue' 
} 

Чтобы сделать вещи хуже, мои лица находятся в табличной переменной.

Итак, у меня есть (в зр с параметром person_id):

--result table 
declare @people_info table 
(
person_id int, 
name nvarchar(max), 
age int, 
height nvarchar(10) null, 
weight nvarchar(10) null, 
eye_color nvarchar(16) null 
) 


insert into @people_info 
select person_id, name, age, null, null, null 
    from dbo.HR.people where person_id = @person_id 

update pi 
set 
    pi.height = (select pa.attribute_value where pa.attribute_type_id = 'Height'), 
    pi.height = (select pa.attribute_value where pa.attribute_type_id = 'Weight'), 
    pi.eye_color = (select pa.attribute_value where pa.attribute_type_id = 'EyeColor') 
from 
    @people_info pi 
    inner join dbo.HR.person_attributes pa on pi.person_id = pa.person_id 

select * from @people_info 

Что, конечно, не работает по какой-то причине. Если я запрошу две связанные таблицы и выберите «pa.attribute_value, где pa.attribute_type_id =« someval », я получаю правильное значение. Но обновление не работает.

Конечно, я могу написать это как три обновления, но я думаю, что будет быстрее сделать одно соединение, а затем фильтровать в предложении update.

Также имейте в виду, что мои атрибуты распространяются на три таблицы, а не только на таблицу атрибутов. Итак, вот почему у меня есть переменная таблицы.

Любая помощь очень приветствуется. Может быть, я ошибаюсь. Вопросы эффективности. Каков наиболее эффективный способ достичь этого?

Большое спасибо.

ответ

1

Попробуйте этот код для обновления с шарниром:

update 
     pi 
    set 
     pi.height = pa.Height 
     pi.weight = pa.Weight 
     pi.eye_color = pa.EyeColor 
    from 
     @people_info pi 
    inner join 
     (
      SELECT 
       person_id 
       ,[Height] Height 
       ,[Weight] Weight 
       ,[EyeColor] EyeColor 
      FROM 
      (
       SELECT 
         attribute_type_id 
        , attribute_value 
        , person_id 
       FROM 
        dbo.HR.person_attributes pa 
      ) pa 
      PIVOT 
      (
       MAX(attribute_value) FOR attribute_type_id IN ([Height],[Weight],[EyeColor]) 
      )pvt 

     ) pa 
    on 
     pi.person_id = pa.person_id 
+0

Нет, это не сработает. Я получаю null для значений, которые я пытаюсь обновить. :) –

+0

Мой плохой, я обновил запрос для работы с точкой поворота, так что у вас есть только один вызов таблицы, пожалуйста, дайте мне знать, если у вас возникли проблемы с выполнением запроса (не проверено). – Farfarak

+0

Спасибо. Это работает и сокращает общее время выполнения в два раза! Я заметил, что он эффективнее всего другого, если ключи (attrib_ids) являются строками. Если мы имеем дело с ints, то нет заметного выигрыша, по крайней мере, в моем наборе данных. –

1

Может быть, вы хотите что-то вроде:

update pi 
set 
    pi.height = paH.attribute_value, 
    pi.weight = paW.attribute_value, 
    pi.eye_color = paE.attribute_value 
from 
    @people_info pi 
    inner join dbo.HR.person_attributes paH on pi.person_id = paH.person_id 
              and paH.attribute_type_id = 'Height' 
    inner join dbo.HR.person_attributes paW on pi.person_id = paW.person_id 
              and paW.attribute_type_id = 'Weight' 
    inner join dbo.HR.person_attributes paE on pi.person_id = paE.person_id 
              and paE.attribute_type_id = 'EyeColor' 
+0

спасибо. хорошо, это работает, но я не уверен, что это лучше с точки зрения производительности, а затем имеет n независимых обновлений. я буду тестировать это завтра! Благодарю. –

+0

При работе с int fks на моем наборе данных это работает так же быстро, как и другой ответ. По крайней мере, насколько я мог это измерить. Однако при работе со строковыми клавишами он намного медленнее. –