在Northwind数据库中按OR条件拼接子表行并过滤有效结果
解决Northwind数据库中分类下符合条件产品名称拼接的问题
你的问题核心是首次尝试的查询没有过滤掉无符合条件产品的分类,同时拼接结果可能存在多余的分隔符开头。下面是两种可行的正确实现方案:
方案1:使用CTE先筛选符合条件的数据集(推荐,逻辑更清晰)
先复刻原查询的筛选逻辑,把所有符合条件的产品和分类记录提取出来,再分组拼接:
WITH FilteredProducts AS ( -- 先获取原查询中所有符合条件的产品+分类记录 SELECT c.CategoryID, 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' ) SELECT CategoryName, -- 用STUFF去掉拼接后开头多余的'-' STUFF( (SELECT '-' + ProductName FROM FilteredProducts fp2 WHERE fp2.CategoryID = fp1.CategoryID ORDER BY ProductName FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '' ) AS ProductNames FROM FilteredProducts fp1 GROUP BY CategoryID, CategoryName -- 按分类分组,确保每个分类只返回一行 ORDER BY CategoryName;
方案2:使用EXISTS过滤无效分类
直接在主查询中通过EXISTS判断分类是否有符合条件的产品,避免返回多余分类:
SELECT c.CategoryName, STUFF( (SELECT '-' + p.ProductName FROM Products p WHERE p.CategoryID = c.CategoryID AND (c.CategoryName LIKE '%on%' OR p.ProductName = 'Vegie-spread') ORDER BY p.ProductName FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '' ) AS ProductNames FROM Categories c -- 关键:只保留有符合条件产品的分类,和原查询结果一致 WHERE EXISTS ( SELECT 1 FROM Products p WHERE p.CategoryID = c.CategoryID AND (c.CategoryName LIKE '%on%' OR p.ProductName = 'Vegie-spread') ) ORDER BY c.CategoryName;
为什么你的首次尝试会返回多余分类?
你用了CROSS APPLY,它会对所有分类执行子查询,哪怕某个分类下没有符合条件的产品,也会返回该分类(此时ProductNames为空)。加上EXISTS条件或者先筛选有效数据集,就能过滤掉这些不符合原查询逻辑的分类。
另外,用STUFF代替直接拼接,是为了去掉结果开头多余的-,让最终格式完全符合你的要求。
内容的提问来源于stack exchange,提问作者Karin
相关产品推荐
相关产品推荐

