我知道你有很多关于这个的话题。但是,我还没有找到满足我需求的。我需要(按需)将选择深层表数据透视到一个宽输出表。这里的问题是我不能将聚合与 Pivot 一起使用,因为它会吃掉输出中所需的响应。我已经想出了一个解决方案,但我认为这不是最好的,因为它需要无数个左连接才能工作。我已将所有尝试和注释包括在内,如下所示:
-- Sql Server 2008 数据库。 -- 深层表结构(不受修改)包含名称/值对,用户 ID 为 ——外键。在许多情况下,用户为 -- itemName 比如如果问他们的种族,可以回答白人+西班牙人等。每个回答都被存储 - 作为单独的记录 - 目前无法更改。 -- 目标:将深层数据转向宽数据,同时压缩结果 - 安定下来。每个 userId 的所有项目的帐户,并复制 -- 适用的列值(而不是显示空值) -- 用于存储单个和多个响应的一些数据的示例表 将@testTable 声明为表(userId int,itemName varchar(50),itemValue varchar(255)) 插入@testTable 选择 1,'q01','1-q01 答案' UNION SELECT 1, 'q02', '1-q02 答案' UNION SELECT 1, 'q03', '1-q03 答案 1' UNION SELECT 1, 'q03', '1-q03 答案 2' UNION SELECT 1, 'q03', '1-q03 答案 3' UNION SELECT 1, 'q04', '1-q04 答案' UNION SELECT 1, 'q05', '1-q05 答案' UNION SELECT 2, 'q01', '2-q01 答案' UNION SELECT 2, 'q02', '2-q02 答案' UNION SELECT 2, 'q03', '2-q03 答案 1' UNION SELECT 2, 'q03', '2-q03 答案 2' UNION SELECT 2, 'q04', '2-q04 答案' UNION SELECT 2, 'q05', '2-q05 答案' 选择“原始数据” 选择 * 从 @TestTable SELECT '使用 Pivot - 显示每个 itemName 的 itemValue 的汇总结果 - 吃掉其他人' ; 数据为 ( 选择 [用户身份] , [项目名称] , [项目值] 从 @testTable ) 选择 [用户身份] , [q02] , [q03] , [q05] 从 数据 枢 ( MIN(itemValue) -- 聚合函数吃掉需要的值。 FOR itemName in ([q02], [q03], [q05]) ) 作为数据透视表 SELECT '聚合与分组 - 导致空值' 选择 不同的用户 ID ,[q02] = Max(CASE WHEN itemName = 'q02' THEN itemValue END) ,[q03] = Max(CASE WHEN itemName = 'q03' THEN itemValue END) ,[q05] = Max(CASE WHEN itemName = 'q05' THEN itemValue END) 从 @testTable 在哪里 itemName in ('q02', 'q03', 'q05') -- 让它变得更快 通过...分组 userId -- 如果仅通过 userId,它只给出 1 行 PERIOD = BAD!! , [项目名称] , [项目值] SELECT '多个左连接 - 工作正常但如果旋转 175 列左右则不好' ; 数据为 ( 选择 用户身份 ,[项目名称] ,[项目值] 从 @testTable 在哪里 itemName in ('q02', 'q03', 'q05') -- 让它变得更快 ) 选择 不同的 s1.userId ,[q02] = s2.[itemValue] ,[q03] = s3.[itemValue] ,[q05] = s5.[itemValue] 从 数据 s1 左连接数据 s2 ON s2.userId = s1.userId AND s2.[itemName] = 'q02' 左连接数据 s3 ON s3.userId = s1.userId AND s3.[itemName] = 'q03' 左连接数据 s5 ON s5.userId = s1.userId AND s5.[itemName] = 'q05'
所以底部查询是唯一一个(到目前为止)可以做我需要做的事情,但是当我使用实际项目名称进行透视时,LEFT JOIN 会失控并导致性能问题。任何建议表示赞赏。