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

我使用的是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中有这样做的方法吗

谢谢


更新:

谢谢你的帮助!我收到两个错误。看起来数据透视要求值为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