Отображаем данные из связанной таблицы в одном поле24 августа 2011
Предположим, что существует какой-то объект с атрибутами. Эти атрибуты хранятся в таблице. Среди этих атрибутов есть такие, которые могут хранить одновременно несколько значений. Для этого используется дополнительная таблица, связь с объектом по 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 нам помогает отсеять дублирование записей, т.к. если исполнителей больше одного, то одинаковых записей будет столько, сколько исполнителей.













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