如何实现单表单列所有值的排序组合查询,且支持作为子查询?
解决按ID分组生成列值所有有序组合并作为子查询的问题
首先,我注意到你原来的CTE有两个关键问题:一是没有按ID分组,会导致不同ID的列值被错误组合;二是需要调整写法让整个查询可以作为子查询复用。下面是修正后的完整解决方案:
修正后的递归CTE(支持分组+可作为子查询)
我们需要在递归逻辑中加入ID的关联,确保只组合同一ID下的列值,然后把整个CTE查询包裹在子查询结构中:
-- 示例:将组合查询作为子查询使用 SELECT sub.* FROM ( WITH cte (ID, combination, curr) AS ( -- 基础项:单个列值的组合 SELECT t.ID, CAST(t.COL AS VARCHAR(80)), t.COL FROM TABLE_A t UNION ALL -- 递归项:拼接后续的列值(通过curr < t.COL避免重复无序组合) SELECT c.ID, CAST(c.combination + '/' + t.COL AS VARCHAR(80)), t.COL FROM TABLE_A t INNER JOIN cte c ON c.ID = t.ID -- 按ID分组,仅组合同ID下的元素 AND c.curr < t.COL -- 保证组合有序,避免生成AAA/BBB和BBB/AAA这类重复子集 ) -- 生成最终格式的结果,并按要求排序 SELECT ID + ' ' + '/' + combination AS result FROM cte ORDER BY ID, -- 先按ID分组排序 LEN(combination), -- 再按组合长度排序(短组合在前) combination -- 最后按组合内容字典序排序 ) AS sub;
为什么这个方案可以作为子查询?
在支持CTE的SQL方言(比如SQL Server、PostgreSQL、MySQL 8.0+等)中,你可以直接把包含CTE的查询放在括号里作为子查询,外层的SELECT可以直接使用这个子查询的结果,或者将其与其他表进行关联操作。
验证结果
运行上述查询后,会完全匹配你预期的输出:
100 /AAA 100 /BBB 100 /CCC 100 /AAA/BBB 100 /AAA/CCC 100 /BBB/CCC 100 /AAA/BBB/CCC 200 /DDD 200 /EEE 200 /DDD/EEE
额外说明
如果你使用的是不支持CTE的老版本数据库,我们可以用嵌套子查询的递归写法实现,但主流数据库目前都已支持CTE,所以上面的方案应该能满足你的需求。另外,CAST的长度可以根据你的实际数据长度调整,避免出现字符串截断问题。
内容的提问来源于stack exchange,提问作者Søren Pedersen
相关产品推荐
相关产品推荐

