2017-09-29 2 views
2

J'ai une table avec les données suivantespivot à plusieurs SQL Server

+-----------+-----------+----------+----------+--------+ 
| SourceZip | TargetZip | TargetID | Distance | rowNum | 
+-----------+-----------+----------+----------+--------+ 
|  00602 |  08831 | 14780 | 1567.579 | R1  | 
|  00602 |  08831 |  6398 | 1567.579 | R2  | 
|  00602 |  07747 |  4290 | 1570.665 | R3  | 
|  00603 |  08831 | 14780 | 1561.272 | R1  | 
|  00603 |  08831 |  6398 | 1561.272 | R2  | 
|  00603 |  07747 |  4290 | 1564.328 | R3  | 
+-----------+-----------+----------+----------+--------+ 

Je en ai besoin dans le format suivant

+-----------+-------------+-------------+-------------+-------------+-------------+-------------+ 
| SourceZip | R1_TargetID | R1_Distance | R2_TargetID | R2_Distance | R3_TargetID | R3_Distance | 
+-----------+-------------+-------------+-------------+-------------+-------------+-------------+ 
|  00602 |  14780 | 1567.579 |  6398 | 1567.579 |  4290 | 1570.665 | 
|  00603 |  14780 | 1561.272 |  6398 | 1561.272 |  4290 | 1564.328 | 
+-----------+-------------+-------------+-------------+-------------+-------------+-------------+ 

On m'a dit que je peux utiliser un seul pivot pour cette , mais chaque exemple de pivot que je peux trouver utilise une fonction d'agrégation et génère une seule colonne pour les données pivotées.

Est-ce quelque chose que je peux faire avec un seul pivot, ou ai-je besoin de générer deux tableaux croisés dynamiques distincts (un pour chaque TargetID et Distance) et ensuite les joindre?

MISE À JOUR

J'ai fini par combiner les champs dont j'ai besoin en une seule valeur qui peut parser dans l'application des données est Transmis à

select * 
from (SELECT SourceZip, CONVERT(varchar(10), TargetID)+ '|' + CONVERT(varchar(10), Distance) as TargetSite, rowNum 
     FROM Targets 
    ) as SourceTable 

pivot (min(TargetSite) 
for rowNum in (R1 
       ,R2 
       ,R3 
       ) 
    ) as pivottable 

Ce n'est pas idéal, mais il fonctionne.

Je encore apprécier des suggestions pour faire pivoter plusieurs colonnes

Répondre

2

S'il est possible de convertir en colonne pour pivoter même type, vous pouvez utiliser cette approche.

DECLARE @MyTable TABLE (SourceZip VARCHAR(10), TargetZip VARCHAR(10),TargetID INT, Distance VARCHAR(10), rowNum VARCHAR(10)) 

INSERT INTO @MyTable VALUES 
('00602','08831','14780','1567.579','R1'), 
('00602','08831','6398','1567.579','R2'), 
('00602','07747','4290','1570.665','R3'), 
('00603','08831','14780','1561.272','R1'), 
('00603','08831','6398','1561.272','R2'), 
('00603','07747','4290','1564.328','R3') 

SELECT * FROM 
    (
     SELECT SourceZip, 
      CONVERT(VARCHAR(20),TargetID) [TargetID_Distance], 
      rowNum + '_TargetID' rowNum 
      FROM @MyTable 
     UNION ALL 
     SELECT SourceZip, 
      CONVERT(VARCHAR(20),Distance) [TargetID_Distance], 
      rowNum + '_Distance' rowNum 
     FROM @MyTable 
    ) SRC 
    PIVOT (MAX([TargetID_Distance]) 
      FOR rowNum IN ([R1_TargetID], 
          [R1_Distance], 
          [R2_TargetID], 
          [R2_Distance], 
          [R3_TargetID], 
          [R3_Distance])) PVT 

Résultat:

SourceZip R1_TargetID   R1_Distance   R2_TargetID   R2_Distance   R3_TargetID   R3_Distance 
---------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- 
00602  14780    1567.579    6398     1567.579    4290     1570.665 
00603  14780    1561.272    6398     1561.272    4290     1564.328 
+0

Merci, ça l'a fait. J'ai fini par couler les deux comme des flotteurs au lieu de varchars et cela a fonctionné comme un charme. – Broom

1

Vous voulez une ligne par SourceZip:

... 
GROUP BY SourceZip; 

Maintenant, vous voulez une colonne de R1_TargetID:

SELECT 
    SUM(CASE WHEN rowNum = 'R1' THEN TargetID END) R1_TargetID, 

Le case remplace tout ce qui n'est pas rowNum = 'R1' par null (en raison de l'implicite else null clause). null est ignoré par sum. Tant que seule une ligne a rowNum = 'R1', ce sera le même résultat que la valeur d'origine.

Les autres colonnes peuvent faire de même:

SUM(CASE WHEN rowNum = 'R1' THEN Distance END) R1_Distance 
... 

En savoir plus sur cette technique: http://modern-sql.com/use-case/pivot

+0

upvoted pour l'approche et l'excellent lien des ressources. Merci de m'avoir appris quelque chose de nouveau, même si j'ai fini par ne pas utiliser cette approche – Broom