SQL Server 2012多表查询需求:从表B提取多组Price列展示
解决SQL Server 2012中行转列的查询需求
嘿,我来帮你搞定这个问题!你需要把表B里不同idB对应的price拆成单独的列,和表A的id、name一一对应,对吧?这其实是典型的行转列场景,在SQL Server 2012里有几种实用的实现方式,下面给你详细说明:
方案1:用CASE WHEN手动映射(适合idB值固定的情况)
这个方法直观易懂,适合新手,也方便你自定义列名:
SELECT A.id AS [A.id], A.name AS [A.name], -- 针对每个idB取值,提取对应的price,没有则显示NULL MAX(CASE WHEN B.idB = 0 THEN B.price END) AS [B.Price(idB=0)], MAX(CASE WHEN B.idB = 1 THEN B.price END) AS [B.Price(idB=1)], MAX(CASE WHEN B.idB = 3 THEN B.price END) AS [B.Price(idB=3)] FROM 表A A -- 用LEFT JOIN保证表A的所有记录都能显示,哪怕表B里没有对应数据 LEFT JOIN 表B B ON A.id = B.[id(A)] -- 按表A的id和name分组,确保每个A的记录只出现一次 GROUP BY A.id, A.name -- 按id排序,和原表顺序一致 ORDER BY A.id;
方案2:用PIVOT函数(更简洁的行转列方式)
SQL Server自带的PIVOT函数专门用来处理这种行转列场景,代码更简洁:
SELECT [A.id], [A.name], -- 给转后的列重命名成你需要的格式 [0] AS [B.Price(idB=0)], [1] AS [B.Price(idB=1)], [3] AS [B.Price(idB=3)] FROM ( -- 先关联两张表,获取基础数据 SELECT A.id AS [A.id], A.name AS [A.name], B.idB, B.price FROM 表A A LEFT JOIN 表B B ON A.id = B.[id(A)] ) AS SourceTable -- 用PIVOT把idB的取值转成列,MAX(price)是聚合规则(因为每个A.id+idB组合唯一) PIVOT ( MAX(price) FOR idB IN ([0], [1], [3]) ) AS PivotTable ORDER BY [A.id];
方案3:动态SQL(适合idB值会新增的情况)
如果以后表B里会新增idB的值,不想每次都修改查询语句,可以用动态SQL自动生成所有列:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX); -- 自动获取表B中所有唯一的idB值,拼接成列名格式 SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(idB) FROM 表B FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'),1,1,'') -- 生成完整的动态查询语句 SET @query = 'SELECT [A.id], [A.name], ' + @cols + ' FROM ( SELECT A.id AS [A.id], A.name AS [A.name], B.idB, B.price FROM 表A A LEFT JOIN 表B B ON A.id = B.[id(A)] ) AS SourceTable PIVOT ( MAX(price) FOR idB IN (' + @cols + ') ) AS PivotTable ORDER BY [A.id]' -- 执行动态生成的SQL语句 EXECUTE sp_executesql @query;
以上三种方案都能得到你预期的结果,其中前两种适合idB固定的场景,第三种适合idB会动态变化的场景,你可以根据实际情况选择~
内容的提问来源于stack exchange,提问作者OSRO
相关产品推荐
相关产品推荐

