2010-05-13 4 views
1

J'ai une table (en fait une vue, mais simplifié mon exemple à une table) qui me donne des données comme celui-ciConversion des lignes à colonnes dans SQL

CompanyName website 
Google   google.com 
Google   google.net 
Google   google.org 
Google   google.in 
Google   google.de 
Microsoft  Microsoft.com 
Microsoft  live.com 
Microsoft  bing.com 
Microsoft  hotmail.com 

Je cherche à le convertir pour obtenir un résultat comme celui-ci

CompanyName website1  website2 website3 website 4 website5 website6 
----------- ------------- ---------- ---------- ----------- --------- -------- 
Google  google.com google.net google.org google.in google.de NULL 
Microsoft Microsoft.com live.com bing.com hotmail.com NULL  NULL 

J'ai regardé en pivot mais il semble que le compte rendu (les valeurs de ligne) ne peuvent pas être dynamiques (c.-à-ne peut être certaines valeurs prédéfinies).

De plus, s'il y a plus de 6 sites, je veux limiter à la première 6

pivot dynamique est logique, mais je dois l'intégrer dans mon avis ?? Y a-t-il une solution plus simple pour cela?

Voici les scripts SQL

CREATE TABLE [dbo].[Company](

[CompanyName] [varchar](50) NULL, 
[website] [varchar](50) NULL 
) ON [PRIMARY] 
GO 

insert into company values ('Google','google.com') 
insert into company values ('Google','google.net') 
insert into company values ('Google','google.org') 
insert into company values ('Google','google.in') 
insert into company values ('Google','google.de') 
insert into company values ('Microsoft','Microsoft.com') 
insert into company values ('Microsoft','live.com') 
insert into company values ('Microsoft','bing.com') 
insert into company values ('Microsoft','hotmail.com') 

Edit: Je dépose de l'ID comme il a été créé pour simplifier. Je pense que je ne devrais pas avoir it.Sorry à ce sujet

+0

Pouvez-vous nous en dire un peu plus sur Pourquoi vous le voulez comme ça? Est-ce pour la présentation ou pour la consommation par un autre programme? – mdma

+0

Ceci est pour la consommation par un autre programme – ram

Répondre

2

essayez ceci:

DECLARE @Company table (
    [id] [int] NULL, 
    [CompanyName] [varchar](15) NULL, 
    [website] [varchar](15) NULL 
) 

insert into @company values (1,'Google','google.com') 
insert into @company values (2,'Google','google.net') 
insert into @company values (3,'Google','google.org') 
insert into @company values (4,'Google','google.in') 
insert into @company values (5,'Google','google.de') 
insert into @company values (6,'Microsoft','Microsoft.com') 
insert into @company values (7,'Microsoft','live.com') 
insert into @company values (8,'Microsoft','bing.com') 
insert into @company values (9,'Microsoft','hotmail.com') 

;WITH CompanyGrouped AS 
( SELECT 
     *,ROW_NUMBER() OVER(PARTITION BY CompanyName ORDER BY CompanyName, id) AS ColumnNumber 
     FROM @company 
) 
SELECT DISTINCT 
    t.CompanyName 
     ,t1.website AS website1,t2.website AS website2,t3.website AS website3, t4.website AS website4, t5.website AS website5, t6.website AS website6 
    FROM @Company      t 
     LEFT OUTER JOIN CompanyGrouped t1 ON t.CompanyName=t1.CompanyName AND t1.ColumnNumber=1 
     LEFT OUTER JOIN CompanyGrouped t2 ON t.CompanyName=t2.CompanyName AND t2.ColumnNumber=2 
     LEFT OUTER JOIN CompanyGrouped t3 ON t.CompanyName=t3.CompanyName AND t3.ColumnNumber=3 
     LEFT OUTER JOIN CompanyGrouped t4 ON t.CompanyName=t4.CompanyName AND t4.ColumnNumber=4 
     LEFT OUTER JOIN CompanyGrouped t5 ON t.CompanyName=t5.CompanyName AND t5.ColumnNumber=5 
     LEFT OUTER JOIN CompanyGrouped t6 ON t.CompanyName=t6.CompanyName AND t6.ColumnNumber=6 

Sortie:

CompanyName website1  website2 website3 website4 website5 website6 
----------- ------------- ---------- ---------- ----------- --------- -------- 
Google  google.com google.net google.org google.in google.de NULL 
Microsoft Microsoft.com live.com bing.com hotmail.com NULL  NULL 

(2 row(s) affected) 
2

Si vous utilisez SQL Server 2005+ vous pouvez faire quelque chose comme ceci:

With NumberedSites As 
    (
    Select CompanyName, Website 
     , ROW_NUMBER() OVER(PARTITION BY CompanyName ORDER BY Id) As Num 
    From Table 
    ) 
Select CompanyName 
    , Min(Case When Num = 1 Then Website End) As Website1 
    , Min(Case When Num = 2 Then Website End) As Website2 
    , Min(Case When Num = 3 Then Website End) As Website3 
    , Min(Case When Num = 4 Then Website End) As Website4 
    , Min(Case When Num = 5 Then Website End) As Website5 
    , Min(Case When Num = 6 Then Website End) As Website6 
From NumberedSites 
Where Num <= 6 
Group By CompanyName 

Maintenant, cette solution est évidemment pas dynamique et prend six colonnes (sept, y compris le nom de la société). Si vous voulez un ensemble dynamique de colonnes, la seule façon de le faire est avec un code SQL dynamique. Au lieu de cela, si vous voulez un tableau croisé dynamique, je suggère de le faire dans le niveau intermédiaire ou dans un outil de reporting.

+0

Merci, cela m'a aidé à résoudre un problème similaire. – DanDan

0

je devais attaquer un rapport similaire pour mon travail, mais je suis venu à lui d'une autre direction. J'ai écrit (aped) un agrégat personnalisé SQL CLR pour enrouler la liste de sites Web en tant que chaîne séparée par des virgules.

Par exemple:

--load the temp table named Company from your example 
--then run this query 
SELECT CompanyName, StringUtil.Concat(Website) AS WebSites FROM Company 

--outputs: 

CompanyName Websites 
----------- --------------------------------------------------- 
Google  google.com, google.net, google.org, google.in, google.de 
Microsoft microsoft.com, live.com, bing.com, hotmail.com 

(2 row(s) affected) 

Le code et les instructions pour construire/installer/en utilisant une commande CLR globale sont livrés avec SQL Server (2005 et plus), mais ne sont généralement pas installés. Les documents sont sur MSDN http://msdn.microsoft.com/en-US/library/ms161551(v=SQL.90).aspx

+0

Oh oui, aussi, les agrégats personnalisés CLR sont étonnamment rapides. Comme 10000x plus rapide que d'utiliser un curseur – tgolisch

Questions connexes