2017-10-04 3 views
2

À l'aide de SQL Server, j'essaie de diviser les informations partagées dans une colonne en trois en fonction du nombre d'ID. Idéalement, j'aurais des identifiants distincts à la fin.SQL Server: fractionner une colonne avec des données variées dans 3 colonnes spécifiques regroupées par ID

Il peut y avoir de 1 à 3 lignes par PersonID selon les informations dans la colonne de contact.

Si un personID apparaît plus d'une fois, j'aimerais que les données soient divisées en deux colonnes, une pour le téléphone et une pour le courrier électronique.

Je devrais vérifier que les données contenaient un "@" symbole pour qu'il soit mis dans la colonne Email, et le reste mis en Phone ou Alt Phone.

C'est assez difficile à expliquer, donc si vous avez besoin de plus d'informations, veuillez commenter.

Espérons que l'exemple ci-dessous aidera:

PersonID Name Contact 
---------------------------------------- 
1   Chen 212747 
1   Chen [email protected] 
2   Pudge 18191 
2   Pudge 18182222 
2   Pudge [email protected] 
3   Riki [email protected] 
3   Riki 19192 
4   Lina 18424 

Je veux convertir en:

PersonID Name Phone Alt Phone Email 
-------------------------------------------------------- 
1   Chen 212747 NULL  [email protected] 
2   Pudge 18191 18182222 [email protected] 
3   Riki 19192 NULL  [email protected] 
4   Lina 18424 NULL  NULL 

Répondre

2
declare @Table AS TABLE 
(
    PersonID INT , 
    Name VARCHAR(100), 
    Contact VARCHAR(100) 
) 
INSERT @Table 
     (PersonID, Name, Contact) 
VALUES 
(1   ,'Chen','212747'), 
(1   ,'Chen','[email protected]'), 
(2   ,'Pudge','18191'), 
(2   ,'Pudge','18182222'), 
(2   ,'Pudge','[email protected]'), 
(3   ,'Riki','[email protected]'), 
(3   ,'Riki','19192'), 
(4   ,'Lina','18424') 

SELECT 
    xQ.PersonID, 
    xQ.Name, 
    MAX(CASE WHEN xQ.IsEmail = 0 AND xQ.RowNumberPhone = 1 THEN xQ.Contact ELSE NULL END) AS Phone, 
    MAX(CASE WHEN xQ.IsEmail = 0 AND xQ.RowNumberPhone = 2 THEN xQ.Contact ELSE NULL END) AS [Alt Phone], 
    MAX(CASE WHEN xQ.IsEmail = 1 AND xQ.RowNumberEmail = 1 THEN xQ.Contact ELSE NULL END) AS Email 
FROM 
(
    SELECT * 
     ,CASE WHEN PATINDEX('%@%',T.Contact)>0 THEN 1 ELSE 0 END AS IsEmail 
     ,RANK() OVER(PARTITION BY T.PersonID, CASE WHEN PATINDEX('%@%',T.Contact)=0 THEN 1 ELSE 0 END ORDER BY T.Contact) AS RowNumberPhone 
     ,RANK() OVER(PARTITION BY T.PersonID, CASE WHEN PATINDEX('%@%',T.Contact)>0 THEN 1 ELSE 0 END ORDER BY T.Contact) AS RowNumberEmail 
    FROM @Table AS T 
)AS xQ 
GROUP BY 
    xQ.PersonID, 
    xQ.Name 
ORDER BY xQ.PersonID 
+0

Merci beaucoup cela semble être exactement ce dont j'ai besoin – TLCONE

+0

@TLCONE p bail, lisez cette règle https://stackoverflow.com/help/someone-answers, évitez de dire merci, s'il vous plaît marquer cette réponse comme correcte et ajouter un +1 aux autres qui vous ont aidé –

2

En utilisant le numéro de ligne et le groupe par personne id vous pouvez obtenir le même en dessous de la requête.

Select PersonID, max(Name) name, 
     max(case when rn=1 and contact not like '%@%' then contact end) phone, 
     max(case when rn=2 and contact not like '%@%' then contact end) Alt_Phone, 
     max(case when contact like '%@%' then contact end) mailid 
    from(select t.*, row_number() over(partition by personid order by contact) as rn from table t) as t2 
    group by PersonID 
+0

@VictorHugoTerceros En fait, je répondais à partir de mon portable à l'time.I édité à nouveau, il – Rams

+0

est comment il peut être maintenant –

2

Vous pouvez le faire en utilisant les sous-requêtes

declare @tbl table(PersonID int,Name varchar(50),Contact varchar(100)) 
insert into @tbl 
select 1,'Chen','212747' union 
select 1,'Chen','[email protected]' union 
select 2,'Pudge','18191' union 
select 2,'Pudge','18182222' union 
select 2,'Pudge','[email protected]' union 
select 3,'Riki','[email protected]' union 
select 3,'Riki','19192' union 
select 4,'Lina','18424' 

SELECT DISTINCT 
M.PersonID 
,M.Name 
,(SELECT TOP 1 Contact FROM @tbl WHERE PersonID = M.PersonID AND Contact NOT LIKE '%@%' ORDER BY Contact) AS Phone 
,(SELECT TOP 1 Contact FROM @tbl WHERE PersonID = M.PersonID AND Contact NOT LIKE '%@%' 
    AND Contact NOT IN (SELECT TOP 1 Contact FROM @tbl WHERE PersonID = M.PersonID AND Contact NOT LIKE '%@%' ORDER BY Contact)) AS AltPhone 
,(SELECT TOP 1 Contact FROM @tbl WHERE PersonID = M.PersonID AND Contact LIKE '%@%') AS Email 
FROM @tbl M 

sortie

1 Chen 212747  NULL [email protected] 
2 Pudge 18182222 18191 [email protected] 
3 Riki 19192  NULL [email protected] 
4 Lina 18424  NULL NULL