Как получить результат LEFT объединения в другую таблицу как одно поле - PullRequest
0 голосов
/ 27 октября 2011

Не уверен, как это описать, поэтому я покажу пример:

таблица СТРАНИЦЫ

id      int
parent  int
name    nvarchar
status  tinyint

таблица PAGES_MODULES

id          int 
id_parent   int
module_type nvarchar
module_id   int
status      int

На одной странице может быть несколько связанных модулей. Пример записи:

id    parent    name     status
1     -1        Xyz      1
2     -1        Yqw      1

id    id_parent    module_type    module_id     status
1     1            ARTICLE        1             1
2     1            GALLERY        2             1
3     2            CATEGORY       3             1

Мне нужно создать select, который не вернет 2 результата, если я выберу left join page_modules.

Я хотел бы иметь select, который возвращает связанные модули, как это:

id    parent    name     status    modules
1     -1        Xyz      1         ARTICLE GALLERY
2     -1        Yqw      1         CATEGORY

Возможно ли это?

Спасибо.

UPDATE

Я пробовал COALESE, CROSS APPLY и SELECT в методах SELECT и пришел к следующим выводам:

http://blog.feronovak.com/2011/10/multiple-values-in-one-column-aka.html

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

Ответы [ 4 ]

2 голосов
/ 27 октября 2011

Вам необходимо создать пользовательскую функцию агрегирования, которая может объединять строки, нет встроенной функции SQL Server, которая делает это.

Вы можете создать пользовательскую функцию агрегирования (если вы используетепоследняя версия SQL) с использованием сборки .Net.Вот справочник MS о том, как это сделать (пример в статье на самом деле предназначен для функции CONCATENATE, как вам требуется): http://msdn.microsoft.com/en-us/library/ms182741.aspx

1 голос
/ 27 октября 2011
-- ==================
-- sample data
-- ==================
declare @pages table
(
    id int,
    parent int,
    name nvarchar(max),
    status tinyint
)

declare @pages_modules table
(
    id int,
    id_parent int,
    module_type nvarchar(max),
    module_id int,
    status int
)

insert into @pages values (1, -1, 'Xyz', 1)
insert into @pages values (2, -1, 'Yqw', 1)

insert into @pages_modules values (1, 1, 'ARTICLE', 1, 1)
insert into @pages_modules values (2, 1, 'GALLERY', 2, 1)
insert into @pages_modules values (3, 2, 'CATEGORY', 3, 1)


-- ==================
-- solution
-- ==================
select 
    *,
    modules = (
        select module_type + ' ' from @pages_modules pm
        where pm.id_parent = p.id
        for xml path('')
    )
from @pages p
1 голос
/ 27 октября 2011

Используйте group_concat () , чтобы поместить данные из нескольких строк в одно поле, подобное этому. Обратите внимание, что он имеет ограничение по длине (по умолчанию 1024 символа), поэтому, если вы собираетесь иметь zillion records, будучи group_concatted, вы получите только первые несколько строк, если не увеличите предел.

SELECT ..., GROUP_CONCAT(modules SEPARATOR ' ')
FROM ...
GROUP BY ...

Обратите внимание, что это агрегатная функция, поэтому у вас должно быть предложение group-by.

0 голосов
/ 27 октября 2011

Вам необходимо объединить обе таблицы, а затем GROUP BY от pages.id , pages.parent , pages.status , страниц. имя и pages.status . Тогда ваше поле modules в вашем наборе результатов является функцией агрегирования строк, т.е. в Oracle LISTAGG(pages_modules.modules, ' ') as modules.

...