2013-10-09 3 views
6

Итак, я довольно много искал и искал и не мог найти решение. Возможно, моя ситуация уникальна - или, скорее всего, я просто не знаю, что я делаю. Я намного ближе, чем когда я начал, так что это вздымается. В любом случае - здесь мы идем braintrust - любая помощь очень ценится.SQL Join/Pivot/Unpivot = Madness

мне нужно соединить 2 таблицы поиска, которые выглядят, как это (не достаточно очков, репы еще размещать изображения так, вот мои притвориться, таблицы):

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 

Это то, что я хочу. Я попробовал несколько вещей, в том числе и цапф unpivots, крест применить - но я не могу показаться, чтобы получить этот результат:

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

я буду иметь возможность работать с этим, у меня нет никакой пользы для social_network_id или call_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-сервер 2012 - SSMS.

RESOLVED Я использовал ответ, предоставленный Bluefeet ниже, и он работал как шарм. Также благодаря Ча, чтобы найти время, чтобы помочь.

+0

Just ** ** этих трех сетей или если ручка запроса ** любое число ** из них до тех пор, пока они находятся в таблице «Социальная сеть»? Если всего три, вы должны уйти с тремя конструкциями 'CASE WHEN'. –

+0

Какой RDMS вы используете? –

+0

Cross Применить MSSQL только я думаю. @ apoji187 +1 для отличного первого сообщения, хорошо описанного с таблицей создает и выбирает оператор, предоставленный ... очень очевидно, что вы пытались решить сами. В будущем не забудьте добавить базу данных, с которой вы работаете в тегах, чтобы люди знали, какой SQL-код используется ... cross apply/cross join синтаксис очень уникален для разных баз данных. – Twelfth

ответ

3

Ваш текущий запрос действительно близок. Если ваши таблицы выше являются правильной структурой, то, похоже, вам не нужно использовать CROSS APPLY, потому что у вас нет ничего, что нужно было бы отключить.

Если вы удалите CROSS ОТНОСИТЬСЯ, то вы можете легко получить результат с помощью 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

Прежде всего благодарю вас за то, что нашли время для обзора и создали скрипку. Также спасибо за динамический пример. Надеюсь, все это окажется полезным для кого-то другого. Я чувствую себя глупо из-за размышлений о запросе, но отчаяние - забавная вещь. Еще раз спасибо. – apoji187

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 для PIVOT

SQL Fiddle

Смежные вопросы