根据其他两列中的值来旋转一列中的行值

时间:2019-06-19 16:54:22

标签: c# sql-server tsql ssis etl

针对my last question展开有关SQL查询或C#代码的操作,这些代码可以根据另一列中的数据将一列中的值旋转或转置为不同的列:

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

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

Started POST "/dashboard/websites/db9cfdc39a7e251859f525b911466fd7/toggle_special_category?c=database-research" for 172.21.0.3 at 2019-06-19 15:14:53 +0000
Processing by Dashboard::WebsitesController#toggle_special_category as */*
  Parameters: {"c"=>"database-research", "id"=>"db9cfdc39a7e251859f525b911466fd7", "website"=>{}}
Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)

我需要输出表如下所示:

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

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

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

使用T-SQL透视数据,即

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

...由于MAX的汇总,不会返回所有值。

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

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

2 个答案:

答案 0 :(得分: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和用户的多行。

答案 1 :(得分:0)

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

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