SQL:如何对数据透视列共享相同名称的表进行数据透视?
我使用的是SQL Server 2008 R2版本10.50.1600.1 我试图用字符串透视表,但透视列共享相同的名称。这就是我的数据 +------------+-----------+------------+ | patient_ID | code_type | code_value | +------------+-----------+------------+ | 1 | ICD9 | V70 | | 1 | ICD9 | 401.9 | | 1 | ICD9 | 616 | | 1 | ICD9 | 338.21 | | 2 | ICD9 | V10 | | 2 | ICD9 | 250 | +------------+-----------+------------+ +------------+-----------+------------+ |患者ID |代码|类型|代码|值| +------------+-----------+------------+ |1 | ICD9 | V70| |1 | ICD9 | 401.9| |1 | ICD9 | 616| |1 | ICD9 | 338.21| |2 | ICD9 | V10| |2 | ICD9 | 250| +------------+-----------+------------+ 我想说的是 +------------+--------+--------+--------+--------+--------+--------+ | patient_id | ICD9_1 | ICD9_2 | ICD9_3 | ICD9_4 | ICD9_5 | ICD9_x | +------------+--------+--------+--------+--------+--------+--------+ | 1 | V70 | 401.9 | 616 | 338.21 | null | null | | 2 | V10 | 250 | null | null | null | null | +------------+--------+--------+--------+--------+--------+--------+ +------------+--------+--------+--------+--------+--------+--------+ |患者id | ICD9 | 1 | ICD9 | 2 | ICD9 | 3 | ICD9 | 4 | ICD9 | 5 | ICD9 | x| +------------+--------+--------+--------+--------+--------+--------+ |1 | V70 | 401.9 | 616 | 338.21 |空|空| |2 | V10 | 250 |空|空|空|空| +------------+--------+--------+--------+--------+--------+--------+ ICD9_x可以扩展到无穷大,因为我不知道给定患者会有多少ICD9代码 在SQL中有这样做的方法吗 谢谢SQL:如何对数据透视列共享相同名称的表进行数据透视?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我使用的是SQL Server 2008 R2版本10.50.1600.1 我试图用字符串透视表,但透视列共享相同的名称。这就是我的数据 +------------+-----------+------------+ | patient_ID | code_type | code_value | +------------+-----------+------------+ | 1 | ICD9 | V70 | | 1 | ICD9
更新: 谢谢你的帮助!我收到两个错误。看起来数据透视要求值为int,因为求和正确吗?有没有一种方法可以将透视表用于字符串值?ICD9代码都是字符串 其次,我犯了一个意想不到的错误。它说“选择列表中的元素数量超过了4096个元素的最大允许数量。”对于大型数据集有解决方案吗
再次感谢 你可以试试这样的东西。我希望这对你有用
DECLARE @cols as varchar(max)
DECLARE @query as varchar(max)
select @cols = (SELECT STUFF((SELECT ',' + QUOTENAME(t.code_type+CAST(row_number() over (partition by patient_id order by patient_id, code_type) as varchar(10)))
FROM YOURTABLE as t
FOR XML PATH('')),1,1,''))
select @query = 'select patient_id, ' + @cols + ' from
(select
code_type+CAST(row_number() over (partition by patient_id order by patient_id, code_type) as varchar(10)) as code_type, SUM(code_value) as code_value from YOURTABLE
group by
code_type+CAST(row_number() over (partition by patient_id order by patient_id, code_type) as varchar(10))) d
Pivot (SUM(code_value) for code_type in (' + @cols + ')) p'
EXECUTE(@query)
您是否有主键或任何列用于订购,以确保代码的顺序正确 如果有,则可以将代码类型值连接到以下输出:
row_number () OVER (PARTITION BY patient_ID, code_type ORDER BY patient_id, /* codes order column here */)
Searvh for dynamic pivot…您应该使用dynamic pivot,这里有更好的解释:[尝试为患者或遭遇分配一些独特的东西。一行数字()应该可以让您到达那里。只要它延伸到无穷远,您最多可以有68000+13000(分别为ICD10和9)。这远远超过了SQL中的1024个最大列。谢谢。对于动态数据透视,它对字符串有效吗?我已经搜索了大约,并且所有的动态数据透视都对数据进行了求和。抱歉,我对SQL还是很陌生。谢谢!不幸的是,我有很多患者,并且出现了此错误。选择列表中的元素数超过了最大允许值d 4096个元素的数目。有没有其他方法来处理大型数据集?还有,在求和(code_值)的子查询中,代码值为varchar。这是否仍然可行?我查看了一对动态数据透视表,所有这些表都需要求和值。是否有办法解决此问题?谢谢!谢谢!还有一列是此表的唯一标识符,用作主键。但在数据透视后,我计划使用患者id作为主键y、 但是,我收到了一个意外错误。它说我超过了4096个元素的最大允许数量。我不知道有限制。超过4096个?这听起来像是您试图生成超过4096个列,而每个患者似乎都在样本结果中的单独一行上-所以要获得4096个以上的列,您应该使用4096+r输入时每个患者的ows数,是这样吗?您确定每个患者id的代码计数器从1重新启动吗?我认为可能是这样,但从原始数据看,这似乎不可能。我有大约20k个患者,但我尝试旋转的列仅是诊断列,piv时不应超过20列第二,我可以透视varchar吗?是的,您应该能够透视varchar-您可能需要添加一个聚合函数,在这种情况下,您可以只使用max(),但要小心-为了确保这项工作,您需要确保后缀代码类型的后缀正确(例如,每个客户的计数器/行号都会重置,并且每行都有一个唯一的患者id和后缀代码类型组合,以避免由于max()而“隐藏”数据)。我将尝试用一个示例来改进我的帖子,以使其更清晰。只是用一个示例更新了我的帖子以使其更清晰。
-- Preparing some demo data as per your sample:
DECLARE @YourTable TABLE (
ID INT IDENTITY (1,1) PRIMARY KEY,
patient_id INT,
code_type VARCHAR(20),
code_value VARCHAR(20)
)
INSERT INTO @YourTable
(patient_id, code_type, code_value)
VALUES
(1, 'ICD9', 'V70'),
(1, 'ICD9', '401.9'),
(1, 'ICD9', '616'),
(1, 'ICD9', '338.21'),
(2, 'ICD9', 'V10'),
(2, 'ICD9', '250')
-- That should look like your starting point:
SELECT * FROM @YourTable
-- Now we suffix the code_type:
SELECT
patient_id,
code_type + '_' + cast(
row_number () OVER (PARTITION BY patient_id, code_type ORDER BY patient_id, ID)
AS VARCHAR(20)
) AS code_type,
code_value
FROM
@YourTable
-- ... and finally we pivot:
SELECT
patient_id,
ICD9_1,
ICD9_2,
ICD9_3,
ICD9_4
FROM (
SELECT
patient_id,
code_type + '_' + cast(
row_number () OVER (PARTITION BY patient_id, code_type ORDER BY patient_id, ID)
AS VARCHAR(20)
) AS code_type,
code_value
FROM
@YourTable
) data
PIVOT (
max(code_value)
-- you need to list all here:
FOR code_type IN (ICD9_1, ICD9_2, ICD9_3, ICD9_4)
) piv