我知道你有很多关于这个的话题。但是,我还没有找到满足我需求的。我需要(按需)将选择深层表数据透视到一个宽输出表。这里的问题是我不能将聚合与 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 会失控并导致性能问题。任何建议表示赞赏。