SQL Join / Pivot / Unpivot =疯狂

时间:2013-10-09 21:42:47

标签: sql sql-server sql-server-2012 pivot

所以,我做了很多搜索和摆弄,并没有找到解决方案。也许我的情况很独特 - 或者更有可能我只是不知道我在做什么。我比我开始时更接近,所以这令人振奋。无论如何 - 在这里我们进行了脑力劳动 - 非常感谢任何帮助。

我需要加入两个看起来像这样的查找表(还没有足够的重复点来发布图像所以这里是我的假装表):

Social Network Member [table]
member_id     social_network_id     connection_id_string
16972         1                     www.linkedin.com/somename
16972         2                     www.twitter.com/somename
16972         3                     www.facebook.com/somename
180301        1                     www.linkedin.com/anothername

Social Network [table]
social_network_id     name     calling_string
1                     Linkedin www.linkedin.com
2                     Twitter  www.twitter.com
3                     Facebook www.facebook.com

这就是我想要的。我尝试了很多东西,包括枢轴和非常规,交叉申请 - 但我似乎无法得到这个结果:

member_id   linkedin                     facebook                     twitter
16972       www.linkedin.com/somename    www.facebook.com/somename    www.twitter.com/somename

我将能够使用它,在连接后我没有使用social_network_id或calling_string。这是我的查询并不能完成这项工作。

SELECT member_id, [facebook],[linkedin],[myspace],[twitter]
FROM (
SELECT member_id,name,social_network_id,calling_string,connection_id_string
FROM social_network_member INNER JOIN
social_network ON social_network_member.social_network_id = social_network.social_network_id
CROSS APPLY (VALUES ('NAME',name),
('CONNECTION STRING', connection_id_string),
('CALLING STRING',calling_string))
Unpivoted(club_id,member_id)) as Sourcetable
Pivot (MAX(connection_id_string) For name in([facebook],[linkedin],[myspace],[twitter])) AS PVT

我能说的最好的是十字架申请真的没有做任何事情。我有点猜测那里的语法。你能说出来吗?

这就是我所得到的(有点像我在搜索中看到的那样):

member_id     facebook                  linkedin                    myspace     twitter
16972         NULL                      www.linkedin.com/somename   NULL        NULL
16972         www.facebook.com/somename NULL                        NULL        NULL
...
...

我想要的甚至可能吗?有关如何到达那里的任何指示?我的查询是否全部搞砸了?

先谢谢女士和男士们。

我之前忘了提到这个,但我使用的是SQL Server 2012 - SSMS。

已解决我使用了下面Bluefeet提供的答案,它就像一个魅力。还要感谢Cha花时间提供帮助。

2 个答案:

答案 0 :(得分:3)

您当前的查询非常接近。如果您的上表是正确的结构,那么您似乎不需要使用CROSS APPLY,因为您没有任何需要忽略的内容。

如果您删除了CROSS APPLY,那么您可以使用PIVOT轻松获得结果:

SELECT member_id, [facebook],[linkedin],[myspace],[twitter]
FROM
(
  SELECT m.member_id,
    n.name,
    m.connection_id_string
  FROM social_network_member m
  INNER JOIN social_network n
    ON m.social_network_id = n.social_network_id
) d
pivot
(
  max(connection_id_string)
  for name in ([facebook],[linkedin],[myspace],[twitter])
) piv;

请参阅SQL Fiddle with Demo

如果您有未知数量的值,则可以使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
                    from social_network
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT member_id, ' + @cols + ' 
            from 
            (
              SELECT m.member_id,
                n.name,
                m.connection_id_string
              FROM social_network_member m
              INNER JOIN social_network n
                ON m.social_network_id = n.social_network_id
            ) x
            pivot 
            (
                max(connection_id_string)
                for name in (' + @cols + ')
            ) p '

execute sp_executesql @query;

请参阅SQL Fiddle with Demo

答案 1 :(得分:1)

我认为这是一个非常简单的PIVOT案例。您根本不需要使用CROSS APPLY / JOIN复杂化它。像这样简单的查询将执行:

SELECT member_id, [facebook],[linkedin],[myspace],[twitter]
FROM (
SELECT member_id,name,connection_id_string
FROM social_network_member snm INNER JOIN
social_network sn ON snm.social_network_id = sn.social_network_id
) as Sourcetable
Pivot (MAX(connection_id_string) For [name] in([facebook],[linkedin],[myspace],[twitter])) AS PVT

提示:不要在SourceTable for PIVOT中包含不必要的列

SQL Fiddle