Конкатенация строк ребенка при соблюдении пункта «Где» или - PullRequest
0 голосов
/ 10 мая 2018

У меня есть проблема, когда мне нужно объединить значения дочерней таблицы в одно поле, а также соблюдать условие ИЛИ в предложении where. Допустим, я работаю в базе данных Northwind, и у меня есть запрос, такой как:

SELECT c.CategoryName, p.ProductName FROM Products p join Categories c on p.CategoryID = c.CategoryID
where c.CategoryName like '%on%' or p.ProductName = 'Vegie-spread'
order by c.CategoryName, p.ProductName

Я хочу, чтобы все имена продуктов были объединены в одно поле для каждого имени категории, чтобы поле «Продукты» выглядело так:

Aniseed Syrup-Chef Anton's Cajun Seasoning-Chef Anton's Gumbo Mix-etc.

Моя первая попытка выглядит так:

select c.CategoryName, ISNULL(products.line, '') AS ProductNames
    from Categories c
    cross apply (
        select CAST((select p.ProductName + '-'
        from products p
        where c.CategoryID = p.CategoryID
        and (c.CategoryName like '%on%' or p.ProductName = 'Vegie-spread')
        order by p.ProductName
        for xml path('')) as nvarchar(max)) line
    ) products
order by c.CategoryName

Но это возвращает некоторые категории, которые не соответствуют условиям where. Я хочу, чтобы результаты были такими, как если бы я набрал этот запрос:

SELECT c.CategoryName, p.ProductName FROM Products p join Categories c on p.CategoryID = c.CategoryID
where c.CategoryName like '%on%' or p.ProductName = 'Vegie-spread'
order by c.CategoryName, p.ProductName

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

Может кто-нибудь показать мне, как это сделать?

1 Ответ

0 голосов
/ 10 мая 2018

"Грубая сила" им.Начните с запроса «как будто»:

SELECT c.CategoryName, p.ProductName FROM Products p join Categories c on p.CategoryID = c.CategoryID
where c.CategoryName like '%on%' or p.ProductName = 'Vegie-spread'
order by c.CategoryName, p.ProductName

И используйте его как CTE или производную таблицу, а затем примените логику FOR XML PATH к этому CTE вместо базовой таблицы, чтобы «объединить группу»строк продукта в одну.

Вот вопрос, который показывает несколько способов выполнения "группового объединения" в SQL Server .

Так что в psuedocode использование CTE будетвыглядят так:

WITH cte AS (
  {Your "as-if" query}
)
SELECT CategoryName, ({code that does a group concat}) AS ProductLine
FROM cte

А в части {code that does a group concat} (как бы вы ни решили это сделать) вы бы аналогичным образом заменили действительное имя таблицы на cte.

...