Запрос, показывающий список ассоциаций в отношениях «многие ко многим» - PullRequest
1 голос
/ 06 октября 2008

У меня есть две таблицы: Книга и Метка , а книги помечаются с использованием таблицы ассоциации BookTag . Я хочу создать отчет, который содержит список книг и для каждой книги список тегов книги. Достаточно идентификаторов тегов, имена тегов не нужны.

Пример:

Book table:
Book ID | Book Name
28      | Dracula

BookTag table:
Book ID | Tag ID
28      | 101
28      | 102

В своем отчете я хотел бы показать, что в книге № 28 есть теги 101 и 102:

Book ID | Book Name | Tags
28      | Dracula   | 101, 102

Есть ли способ сделать это in-line, не прибегая к функциям или хранимым процедурам? Я использую SQL Server 2005.

Обратите внимание, что тот же вопрос уже задавался в Объедините несколько результатов в подзапросе в одно значение, разделенное запятыми , но решение включает создание функции. Я спрашиваю, есть ли способ решить эту проблему без создания функции или хранимой процедуры.

Ответы [ 4 ]

4 голосов
/ 06 октября 2008

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

SELECT em.Code,
    (SELECT et.Name + ' '  AS 'data()'
        FROM tblEmployeeTag et
            JOIN tblEmployeeTagAssignment eta ON et.Id = eta.EmployeeTag_Id AND eta.Employee_Id = em.id
    FOR XML PATH('') ) AS Tags
FROM tblEmployee em

Edit:

Вот полная версия с использованием таблиц и запятой:

SELECT bk.Id AS BookId,
        bk.Name AS BookName,
    REPLACE((SELECT LTRIM(STR(bt.TagId)) + ', '  AS 'data()'
        FROM BookTag bt
        WHERE bt.BookId = bk.Id         
        FOR XML PATH('') ) + 'x', ', x','') AS Tags
FROM Book bk

Полагаю, для дальнейшего использования я должен немного рассказать о том, что происходит. Имя столбца data () - это специальное значение, связанное с оператором FOR XML PATH. Это приводит к тому, что документ XML будет отображаться так, как если бы вы сделали .InnerText в корневом узле результирующего XML.
Оператор REPLACE - это хитрость для удаления запятой. Добавляя уникальный символ (я случайно выбрал 'x') в конец списка тегов, я могу искать символ запятой-пробела и заменять его пустой строкой. Это позволяет мне отрубить только последнюю запятую. Это предполагает, что в ваших тегах никогда не будет этой последовательности символов.

0 голосов
/ 07 октября 2008

Самым чистым решением, вероятно, является использование пользовательской агрегатной функции C # CLR. Мы обнаружили, что это работает очень хорошо. Инструкции по его созданию можно найти по адресу http://dotnet -enthusiast.blogspot.com / 2007/05 / определяемая пользователем агрегатная функция в sql.html

0 голосов
/ 06 октября 2008

Если бы вы знали максимальное количество тегов для книги, вы могли бы использовать сводку, чтобы перенести их в один и тот же ряд, а затем использовать COALESCE, но в целом я не верю, что это так.

0 голосов
/ 06 октября 2008

Если вы не знаете, что такое идентификаторы / имена тегов, и не можете жестко закодировать их в своем запросе, я боюсь, что ответ - нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...