代码之家  ›  专栏  ›  技术社区  ›  Alexandre georges

从观测值创建稀疏矩阵

  •  2
  • Alexandre georges  · 技术社区  · 8 年前

    我是新来的sql server,我是一个r用户,但r不能用于我的巨大数据集(内存不足)。

    我想做的是:

    我想从一个只有两列的表中创建一个稀疏矩阵,我没有任何值列,这看起来很简单,但是我没有找到正确的方法。

    我的数据:

    ID_patient | ID_product
    -----------------------
    123            A
    123            B
    111            C
    222            A
    333            D
    333            E
    

    OUPUT需要:

    ID_patient |   A   |   B   |   C   |   D   |   E   |
    ----------------------------------------------------
    123            1       1
    111                            1
    222            1
    333                                    1       1    
    

    我读到我可以使用按功能分组或透视功能,但我迄今所做的尝试失败了。

    编辑

    我不知道所有的产品,所以正确的方法是使用 动态枢轴 ?

    2 回复  |  直到 8 年前
        1
  •  2
  •   DhruvJoshi    8 年前

    你可以试试 PIVOT

    See demo

    Select * from 
    (select *, copy=Id_product from t)t
    pivot
    (
        count(copy) for ID_product in ([A],[B],[C],[D],[E]))p
    

    如果你不知道A,B,C,D…在动手之前,你应该去做动态旋转

    更新: updated dynamic piv demo

    declare @cols nvarchar(max)
    declare @query nvarchar(max) 
    
    select @cols=  Stuff((select ','+  quotename( ID_product) from
          (select distinct id_product from t) t  for xml path ('')),1,1,'')
    
    select @query='Select * from 
    ( select *, copy=Id_product from t ) t
    pivot
    (count(copy) for ID_product in ( '+@cols+' ))p '
      exec(@query)
    
        2
  •  2
  •   Sreenu131    8 年前

    试试这个

    IF OBJECT_ID('tempdb..#Temp')IS NOT NULL 
    DROP TABLE #Temp
    
    DECLARE @temp AS TABLE (ID_patient INT, ID_product varchar(10))
    INSERT INTO @temp
    SELECT 123,'A' UNION ALL
    SELECT 123,'B' UNION ALL
    SELECT 111,'C' UNION ALL
    SELECT 222,'A' UNION ALL
    SELECT 333,'D' UNION ALL
    SELECT 333,'E'  
    
    
    SELECT * INTO #Temp 
        FROM @temp
    DECLARE @Sql nvarchar(max),
            @Col  nvarchar(max),
            @Col2  nvarchar(max)
    
    SELECT @Col=STUFF((SELECT DISTINCT ', '+QUOTENAME(ID_product) FROM #Temp FOR XML PATH ('')),1,1,'')
    SELECT @Col2=STUFF((SELECT DISTINCT ', '+'ISNULL('+QUOTENAME(ID_product)+','' '') AS '+QUOTENAME(ID_product) FROM #Temp FOR XML PATH ('')),1,1,'')
    
    SET @Sql='
    SELECT ID_patient,'+@Col2+'
    FROM
    (
    SELECT *, DENSE_RANK()OVER( PARTITION BY ID_patient ORDER By ID_patient) AS [Val] FROM #Temp
    )AS Src
    PIVOT 
    (MAX(Val) FOR ID_product IN ('+@Col+')
    )AS PVT '
    PRINT @Sql
    EXEC (@Sql)
    

    结果

    ID_patient  A   B   C   D   E
    ------------------------------
    111         0   0   1   0   0
    123         1   1   0   0   0
    222         1   0   0   0   0
    333         0   0   0   1   1
    
    推荐文章