【问题标题】:Pivoting row values in one column based on values in two other columns根据其他两列中的值旋转一列中的行值
【发布时间】:2019-06-19 16:54:22
【问题描述】:

扩展my last question 的 SQL 查询或 C# 代码,这些代码可以根据另一列的数据将一列中的值转置或转置为不同的列:

在进一步检查数据后,我需要一个脚本或查询,它可以根据其他两列中的值将一列中的行值转换为不同的列。

例如,这里是我当前的数据表:

ID      USERID     ATTRIBUTE       ATTRIBUTE VALUE 
00001   15         Entitlement       80
00001   15         Entitlement       81
00001   15         Permission        90
00001   15         Permission        91
00001   15         Permission        92
00001   16         Entitlement       82
00001   16         Permission        93

我需要输出表看起来像:

ID      USERID        ENTITLEMENT     PERMISSION 
00001   15               80           90
00001   15               81           91
00001   15                            92
00001   16               82           93 

ENTITLEMENT 和 PERMISSION 列中的值按 USERID 分组。

我知道当它们之间的行数不匹配时,两个新列中都会有 Null 值,这没关系,只要每个新列包含所有行值并与正确的 USERID 对应。

使用 T-SQL 透视数据,即

select ID, USERID, ENTITLEMENT, PERMISSION from dbo.Test_Table
pivot (Max(ATTRIBUTE VALUE) for Attribute IN ([ENTITLEMENT], [PERMISSION])) as PivotTable
order by ID asc

...由于 MAX 聚合,不会返回所有值。

上一个答案中的 C# 代码可以正常工作,但同样只考虑 ATTRIBUTE VALUE 列。

再次感谢您对这项任务的任何帮助。 C# 不是我的强项。

【问题讨论】:

    标签: c# sql-server tsql ssis etl


    【解决方案1】:

    您可以通过 DENSE_RANK 使用以下内容

    SELECT 
          CASE WHEN A.ID IS NULL THEN B.ID ELSE A.ID END AS ID,
          CASE WHEN A.USERID IS NULL THEN B.USERID ELSE A.USERID END AS USERID,
          A.[ATTRIBUTEVALUE] ENTITLEMENT,
          B.[ATTRIBUTEVALUE] PERMISSION 
    FROM
        (
          SELECT *,
          DENSE_RANK() over (partition by  ATTRIBUTE order by  ATTRIBUTEVALUE)  RN1 
          FROM  <<yourtable>>
          WHERE ATTRIBUTE = 'Entitlement'
         )A
    FULL OUTER JOIN
         (
          SELECT *,
          DENSE_RANK() over (partition by  ATTRIBUTE order by  ATTRIBUTEVALUE)  RN2 
          FROM <<yourtable>>
          WHERE ATTRIBUTE = 'Permission'
          )B  ON A.RN1 = B.RN2
    ORDER BY 2,3
    

    输出如下所示

     ID         USERID      ENTITLEMENT PERMISSION
     ---------- ----------- ----------- -----------
     00001      15          80          90
     00001      15          81          91
     00001      16          NULL        93
     00001      16          82          92
    

    不幸的是,PIVOT 不支持您希望数据的外观。因为你想为同一个 id 和用户显示多行。

    【讨论】:

      【解决方案2】:

      您可以尝试以下脚本来获得所需的输出-

      SELECT 
      CASE WHEN A.ID IS NULL THEN B.ID ELSE A.ID END AS ID,
      CASE WHEN A.USERID IS NULL THEN B.USERID ELSE A.USERID END AS USERID,
      A.[ATTRIBUTE VALUE] ENTITLEMENT,
      B.[ATTRIBUTE VALUE] PERMISSION 
      FROM
      (
          SELECT *,ROW_NUMBER() OVER(PARTITION BY USERID ORDER BY USERID) RN1 FROM your_table
          WHERE ATTRIBUTE = 'Entitlement'
      )A
      FULL OUTER JOIN
      (
          SELECT *,ROW_NUMBER() OVER(PARTITION BY USERID ORDER BY USERID) RN2 FROM your_table
          WHERE ATTRIBUTE = 'Permission'
      )B
      ON A.RN1 = B.RN2 AND A.USERID = B.USERID
      ORDER BY 2
      

      输出是-

      ID      USERID  ENTITLEMENT PERMISSION 
      00001   15      80          90
      00001   15      81          91
      00001   15      NULL            92
      00001   16      82          93
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多