SQL:将窄表转换为宽表

时间:2016-06-23 19:43:57

标签: sql sql-server oracle

我的问题与已经提出的问题有点类似:Mysql, reshape data from long / tall to wide

我的复杂性伴随着这样一个事实,即我的数据结构可能不稳定,并且可能会根据用户的意愿进行更改。因此,我的列可以根据填充表的字段更改聚合(增长或缩小)。

有关我的表中可能包含的内容的示例,以下是一些记录:

INPUT:

LOCATION        User_Name        Title       Phone
Living Room     Joe Schmo        Worker      12-23
Baseball Park   Jane Doe         Worker      23-34
Backyard        Tiger Woods      Worker      34-45

但标题中存在相当大的可变性,甚至可能位于位置

INPUT:

LOCATION        User_Name        Title        Phone
Living Room     Batman           Manager      9112
Baseball Park   Batman           Manager      9112
Backyard        Batman           Manager      9112

所以我需要做的是,在匹配的位置上,我需要一个包含与位置关联的所有用户的宽表:

输出:

LOCATION        User_Name    Title   Phone   User_Name   Title     Phone
Living Room     Joe Schmo    Worker  12-23   Batman      Manager   9112
Baseball Park   Jane Doe     Worker  23-34   Batman      Manager   9112
Backyard        Tiger Woods  Worker  34-45   Batman      Manager   9112

任何建议提示都将受到高度赞赏。我试图复制这个例子,但显然我如何解释表可以动态扩大或缩小的事实?我试图做枢轴,但我不能让它与多个领域一起工作。

思想?

1 个答案:

答案 0 :(得分:1)

你可以使用PIVOT查询来做到这一点 您需要事先决定结果应该有多宽 - 我的意思是最终结果应该有多少列“组”(名称,标题,电话)。

下面的示例将整个表分为3组(名称+标题+电话)列:

WITH my_data AS (
    SELECT LOCATION, User_Name, Title, Phone,
           trunc( rn / 3 ) as group_number,
           rn - 3 * trunc( rn / 3 ) as rownum_within_group
    FROM (
        SELECT t.* ,
              row_number() over (partition by location order by user_name ) - 1 As rn
        FROM table1 t
    ) t
    -- ORDER BY Location, user_name
)
SELECT * 
FROM my_data
PIVOT (
   MAX( User_name) As user_name,
   MAX( Title ) as Title,
   MAX( Phone ) As Phone
   FOR rownum_within_group IN (0 as G0,1 As G1 ,2 As G2)
)
ORDER BY 1,2;

以及您示例中稍微修改过的数据的示例结果(我添加了额外的“Batman2”+“Batman3”+“Batman4”条目):

LOCATION       GROUP_NUMBER G0_USER_NAME    G0_TITLE    G0_PHONE    G1_USER_NAME    G1_TITLE    G1_PHONE    G2_USER_NAME    G2_TITLE    G2_PHONE
Backyard                 0  Batman          Manager     9112        Tiger Woods     Worker      34-45           
Baseball Park            0  Batman          Manager     9112        Jane Doe        Worker      23-34           
Living Room              0  Batman          Manager     9112        Batman2         Manager     9112        Batman3         Manager     9112
Living Room              1  Batman4         Manager     9112        Joe Schmo       Worker      12-23   

位置Living Room中有5个用户,因此该位置在结果集中分为两行,第一行有3个用户,第二行有2个用户(请参阅示例中的最后两行)上文)。