Получение описаний для нескольких значений идентификатора — SQL Server

У меня есть две таблицы x и y

Таблица x имеет 24 столбца, каждый из которых содержит разные значения идентификатора.

В таблице Y есть столбец значения идентификатора и описание

Мне нужно написать процедуру, запрос или представление, которое возвращает описания для каждого из 24 значений идентификаторов, содержащихся в таблице x, максимально эффективным способом.

Я написал представление, которое вызывает функцию 24 раза. Функция возвращает описание на основе предоставленного идентификатора. Хотя это работает, это не работает особенно хорошо.

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

Вот определение таблицы x (для ясности удалены нерелевантные столбцы)

    [DefinitiveHLATypeId] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NOT NULL,
[A_X] [int] NULL,
[A_Y] [int] NULL,
[B_X] [int] NULL,
[B_Y] [int] NULL,
[Bw_X] [int] NULL,
[Bw_Y] [int] NULL,
[C_X] [int] NULL,
[DRB1_X] [int] NULL,
[DRB1_Y] [int] NULL,
[DRB3_X] [int] NULL,
[DRB3_Y] [int] NULL,
[DRB4_X] [int] NULL,
[DRB4_Y] [int] NULL,
[DRB5_X] [int] NULL,
[DRB5_Y] [int] NULL,
[DQA_X] [int] NULL,
[DQA_Y] [int] NULL,
[DQB_X] [int] NULL,
[DQB_Y] [int] NULL,
[DPA1_X] [int] NULL,
[DPA1_Y] [int] NULL,
[DPB1_X] [int] NULL,
[DPB1_Y] [int] NULL

Вот определение таблицы y (для ясности удалены нерелевантные столбцы)

    [AntigenId] [int] IDENTITY(1,1) NOT NULL,
[AntigenDescription] [varchar](2000) NOT NULL

Связь между двумя таблицами находится между столбцами _X и _Y в таблице x и столбцом AntigenId в таблице Y.

Мне нужно вернуть описание антигена для каждого из столбцов _X и _Y в таблице x.


person Neil    schedule 10.12.2012    source источник
comment
Как эти две таблицы соотносятся друг с другом?   -  person Mahmoud Gamal    schedule 10.12.2012
comment
Пожалуйста, отредактируйте свой вопрос и опубликуйте несколько примеров данных для каждой таблицы, а затем желаемый результат.   -  person Taryn    schedule 10.12.2012


Ответы (2)


Не видя никаких образцов данных в ваших таблицах, если у вас есть таблица с 24 столбцами данных, которые вам нужно сравнить с другой таблицей, есть несколько способов сделать это.

Во-первых, вы можете выполнить несколько объединений таблицы для каждого столбца, как показано ниже:

select *
from tablex x
left join tabley y1
  on x.col1 = y1.id
left join tabley y2
  on x.col2 = y2.id --- add more joins

Я не знаю, будет ли объединение таблиц 24 раза наиболее эффективным, поэтому может быть проще выполнить UNPIVOT для таблицы с 24 столбцами и присоединиться к этому результату:

select x.value,
  y.description
from 
(
  select value, col
  from tablex
  unpivot
  (
    value
    for col in (col1, col2, col3, col4, col5)
  ) unpiv
) x
left join tabley y
  on x.value = y.id

См. SQL Fiddle с демонстрацией.

UNPIVOT аналогичен использованию UNION ALL в tablex для преобразования данных из нескольких столбцов в строки данных, которые упрощают объединение:

select *
from
(
  select col1 value, 'col1' col
  from tablex
  union all
  select col2 value, 'col2' col
  from tablex
  union all
  select col3 value, 'col3' col
  from tablex
  union all
  select col4 value, 'col4' col
  from tablex
  union all
  select col5 value, 'col5' col
  from tablex
) x
left join tabley y
  on x.value = y.id

На основе вашего редактирования ваш запрос будет похож на этот:

select x.value,
  y.AntigenDescription
from 
(
  select DefinitiveHLATypeId, PersonId, value, col
  from tablex
  unpivot
  (
    value
    for col in (A_X, A_Y, B_X, B_Y, Bw_X, Bw_Y,
                    C_X, DRB1_X, DRB1_Y, DRB3_X, DRB3_Y,
                    DRB4_X, DRB4_Y, DRB5_X, DRB5_Y, DQA_X, DQA_Y,
                    DQB_X, DQB_Y, DPA1_X, DPA1_Y,
                    DPB1_X, DPB1_Y
  ) unpiv
) x
left join tabley y
  on x.value = y.AntigenId

Примечание. В долгосрочной перспективе я бы предложил изменить дизайн tablex, потому что такая структура таблицы затруднит доступ к данным.

person Taryn    schedule 10.12.2012
comment
Большое спасибо Bluefeet за предложение unipivot. Я пробую это сейчас! Ценю то, что вы говорите о редизайне, но это устоявшаяся система, и будет нелегко (но не невозможно) внести то, что будет означать серьезное изменение. - person Neil; 10.12.2012
comment
@Neil Я могу понять, что застрял в системе, поэтому я все же предложил решение. Я думаю, что unpivot будет самым простым способом сделать это, тогда вы выполняете только одно соединение с таблицей. - person Taryn; 10.12.2012
comment
Дополнительный вопрос. Есть ли способ вывести col, даже если значение равно NULL? Unpivot работает для каждого столбца со значением, но если только 10 из 24 столбцов имеют значение, возвращается только 10 строк. - person Neil; 10.12.2012
comment
@ Нил, да, вы можете написать подзапрос, который будет иметь isnull() вокруг каждого столбца - аналогично этой демонстрации - sqlfiddle.com/#!3/b2ab0/2. Затем вы вернете ноль для нулевых значений - person Taryn; 10.12.2012
comment
Дополнительный вопрос к @Bluefeet, если я не возражаю. Есть ли способ вывести col, даже если значение равно NULL? Unpivot работает для каждого столбца со значением, но если только 10 из 24 столбцов имеют значение, возвращается только 10 строк. Unpivot для меня новый, поэтому я еще не знаком со всеми его нюансами. - person Neil; 10.12.2012
comment
@ Нил, ты видел это демо? -- sqlfiddle.com/#!3/b2ab0/2 возвращает четные столбцы которые имеют значение null - person Taryn; 10.12.2012
comment
Я видел это сейчас. Пытался отредактировать комментарий через 5 минут, чтобы добавить @. Поскольку у меня не было времени, я написал отдельный комментарий, но вы уже ответили. Большое спасибо за вашу помощь - person Neil; 10.12.2012
comment
@Neil, если какой-либо из ответов вам подходит, обязательно примите его, отметив галочкой слева от ответа. - person Taryn; 10.12.2012

Присоединение

select tbl.col1ID, desc1.desc, tbl.col2ID, desc2.desc
from tbl 
join desc as desc1 
  on desc1.ID = col1ID 
join desc as desc2 
  on desc2.ID = col1ID 
person paparazzo    schedule 10.12.2012
comment
Я ценю, что мог присоединиться к таблице y 24 раза, но хотел посмотреть, есть ли лучшая техника - person Neil; 10.12.2012
comment
Вопрос задавался о наилучшей производительности и не исключал присоединения. - person paparazzo; 10.12.2012
comment
Извиняюсь, @Blam, я ценю, что должен был быть немного более точным в том, что я просил. - person Neil; 10.12.2012