连接子行,同时遵守 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 名称
我遇到一个问题,我需要将子 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
.