sql-server - 连接子行同时尊重 Where 子句与或
问题描述
我有一个问题,我需要将子表的值连接到一个字段中,同时还要尊重 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
我希望将所有产品名称连接到每个类别名称的一个字段中,以便 Products 字段如下所示:
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
除了我希望每个类别有一行与查询匹配的所有产品连接。
有人可以告诉我如何做到这一点吗?
解决方案
“蛮力”吧。从您的“好像”查询开始:
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 中执行“组连接”的几种方法。
所以在伪代码中,使用 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
.