连接子行,同时遵守 Where 子句与 Or

Concatenate Child Rows While Respecting Where Clause With Or

我遇到一个问题,我需要将子 table 的值连接到一个字段中,同时还要考虑 where 子句中的 OR 条件。 假设我在 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

但是 returns 一些类别不符合 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

除了我希望每个类别一行,将所有符合查询的产品串联在一起。

谁能告诉我怎么做?

"Brute Force"吧。从您的 "as if" 查询开始:

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 或派生 table,然后将您的 FOR XML PATH 逻辑应用于该 CTE,而不是将基础 table 应用于 "group concatenate" 产品行合二为一。

Here is a question that shows several ways of doing a "group concat" in SQL Server.

所以在伪代码中,使用 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.

替换您的实际 table 名称