Блог IT-юзера

О программировании, верстке сайтов и не только

Отображаем данные из связанной таблицы в одном поле24 августа 2011

Читало: 776Рубрика: MS SQL Server

Рейтинг записи:

3
Интересный пост

Предположим, что существует какой-то объект с атрибутами. Эти атрибуты хранятся в таблице. Среди этих атрибутов есть такие, которые могут хранить одновременно несколько значений. Для этого используется дополнительная таблица, связь с объектом по ID.

Существует "вьюха", отображающая список объектов с атрибутами.

Как быть, чтобы с помощью "вьюхи" в одном поле отобразить атрибут, имеющий одновременно несколько значений?

Имеем таблицу Objects, в этой таблице хранятся атрибуты объекта. Есть поле ID.

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


Очевидно, что для хранения исполнителей надо использовать дополнительную таблицу. Назовем ее DopAttrs. Таблица имеет столбцы ObjID ( ID объекта) и MemberID (ID исполнителя).

Так же у нас есть справочник сотрудников, например, Users с полями ID и Name.


Есть задача вывести список атрибутов объекта в виде таблицы.


Нет ничего проще написать запрос

select * from Objects

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

Так как у нас есть две таблицы, то напрашивается составить объединенный запрос, что-то вроде такого

select o.*, u.Name
from Objects o left outer join
     DopAttrs d on o.id = d.ObjID left outer join
     Users u on d.MemberID = u.id

Таким образом получим нужный результат, но только в том случае, если исполнитель у объекта только один. Нам это не подходит.

Если у объекта два или более исполнителей, то в результате мы получим 2 и более строк (сколько исполнителей).

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


Данную задачу я решаю следующим образом.


Для объединения исполнителей в одну строку мне нужна будет функция. Я создаю ее:

CREATE FUNCTION [dbo].[f_GetIspolnitel](@ObjID int)
RETURNS varchar(256) AS  
BEGIN 
declare @r1 varchar(256) 
SELECT @r1 = isnull(@r1 + ', ', '') + u.Name
FROM 
	DopAttrs s
	LEFT OUTER JOIN Users u ON s.MemberID = u.ID
 WHERE 
	s.ObjID = @ObjID
return isnull(@r1, '')
END

Т.о. эта функция найдет всех исполнителей объекта и перечислит их через запятую.


Теперь сформируем окончательный запрос:

SELECT DISTINCT o.*, dbo.f_GetIspolnitel(o.ID) as [Исполнитель]
FROM Objects o

В результате получим нужный результат - список атрибутов объектов.

Каждая строка будет соответствовать одному объекту, при этом в столбце [Исполнитель] через запятую будут перечислены исполнители, если их больше одного.

Оператор DISTINCT нам помогает отсеять дублирование записей, т.к. если исполнителей больше одного, то одинаковых записей будет столько, сколько исполнителей.

Оставьте комментарий!

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

Авторизация: Войти через loginza

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

(обязательно)