2011-06-14 5 views
1

J'ai le tableau suivantmeilleure façon de partiellement UNPIVOT paires dans SQL

VendorID EMP1A  EMP2A  EMP1B  EMP2B 
----------- ----------- ----------- ----------- ----------- 
1   4   3   5   4 
2   4   1   5   5 
3   4   3   5   4 
4   4   2   5   5 
5   5   1   5   5 

Je veux UNPIVOT par paires si je reçois les colonnes « A » sur une ligne et les colonnes « B » sur un autre

vendorid employee orders  employee orders 
----------- --------- ----------- --------- ----------- 
1   EMP1A  4   EMP2A  3 
1   EMP1B  5   EMP2B  4 
2   EMP1A  4   EMP2A  1 
2   EMP1B  5   EMP2B  5 
3   EMP1A  4   EMP2A  3 
3   EMP1B  5   EMP2B  4 
4   EMP1A  4   EMP2A  2 
4   EMP1B  5   EMP2B  5 
5   EMP1A  5   EMP2A  1 
5   EMP1B  5   EMP2B  5 

Cela fonctionne, mais il semble que je travaille trop dur

DECLARE @pvt AS TABLE( 
    VendorID INT, 
    EMP1A INT, 
    EMP2A INT, 
    EMP1B INT, 
    EMP2B INT); 

INSERT INTO @pvt VALUES (1,4,3,5,4), 
(2,4,1,5,5), 
(3,4,3,5,4), 
(4,4,2,5,5), 
(5,5,1,5,5) 

;WITH piv1 
    AS (SELECT vendorid, 
       employee, 
       orders 
     FROM (SELECT vendorid, 
         EMP1A, 
         EMP1B 
       FROM @pvt) p 
       UNPIVOT (orders FOR employee IN (EMP1A, EMP1B)) 
       AS 
       unpvt), 
    piv2 
    AS (SELECT vendorid, 
       employee, 
       orders 
     FROM (SELECT vendorid, 
         EMP2A, 
         EMP2B 
       FROM @pvt) p UNPIVOT (orders FOR employee IN (EMP2A, EMP2B)) 
       AS 
       unpvt) 
SELECT piv1.vendorid, 
     piv1.employee, 
     piv1.orders, 
     piv2.employee, 
     piv2.orders 
FROM piv1 
     INNER JOIN piv2 
     ON piv1.vendorid = piv2.vendorid 
      AND RIGHT(piv1.employee, 1) = RIGHT(piv2.employee, 1) 
WHERE 
    piv1.orders > piv2.orders 

note: Ceci est un exemple simplifié et t voici en fait 25 paires qui doivent être converties en rangées et je veux aussi pouvoir facilement filtrer

par exemple. ajouter WHERE piv1.orders = piv2.orders produit

vendorid employee orders  employee orders 
----------- --------- ----------- --------- ----------- 
2   EMP1B  5   EMP2B  5 
4   EMP1B  5   EMP2B  5 
5   EMP1B  5   EMP2B  5 

Répondre

1

s'avère que je travaillais trop dur

WITH piv1 
    AS (SELECT vendorid, 
       employee, 
       orders 
     FROM @pvt p UNPIVOT (orders FOR employee IN (emp1a, emp1b, 
                 emp2a, emp2b)) 
       AS unpvt) 
SELECT piv1.vendorid, 
     piv1.employee, 
     piv1.orders, 
     piv2.employee, 
     piv2.orders 
FROM piv1 
     INNER JOIN piv1 piv2 
     ON piv1.vendorid = piv2.vendorid 
      AND piv1.employee <> piv2.employee 
      AND RIGHT(piv1.employee, 1) = RIGHT(piv2.employee, 1) 
WHERE Substring(piv1.employee, 4, 1) <> '2' 
ORDER BY piv1.vendorid, 
      piv1.employee 

Maintenant, en ajoutant simplement des paires nécessite la mise à jour du UNPIVOT par exemple

@pvt p UNPIVOT (orders FOR employee IN (emp1a, emp1b, 
             emp2a, emp2b, 
             emp1c, emp2c, 
             emp1d, emp2d)) 
1

Est-ce aussi simple?

SELECT 
    vendorid, 
    'EMP1A' AS employee, EMP1A AS [order1], 
    'EMP2A' AS employee, EMP2A AS [order2] 
FROM Mytable 
UNION ALL 
SELECT 
    vendorid, 
    'EMP1B', EMP1B, 
    'EMP2B', EMP2B 
FROM Mytable 

Remarque: vous avez des noms de colonnes ambiguës qui cassera d'autres choses qui utilisent ces données

Pour plus de lignes, ajouter des clauses UNION

... 
UNION ALL 
SELECT 
    vendorid, 
    'EMP1C', EMP1C, 
    'EMP2C', EMP2C 
FROM Mytable 
UNION ALL 
SELECT 
    vendorid, 
    'EMP1D', EMP1D, 
    'EMP2D', EMP2D 
FROM Mytable 
... 

Pour filtrer davantage (besoin de différents noms de colonnes)

SELECT ... 
FROM 
    (
    SELECT 
     vendorid, 
     'EMP1A' AS employee1, EMP1A AS [order1], 
     'EMP2A' AS employee2, EMP2A AS [order2] 
    FROM Mytable 
    UNION ALL 
    SELECT 
     vendorid, 
     'EMP1B', EMP1B, 
     'EMP2B', EMP2B 
    FROM Mytable 
    UNION ALL 
    SELECT 
     vendorid, 
     'EMP1C', EMP1C, 
     'EMP2C', EMP2C 
    FROM Mytable 
    UNION ALL 
    SELECT 
     vendorid, 
     'EMP1D', EMP1D, 
     'EMP2D', EMP2D 
    FROM Mytable 
    ... 
    ) foo 
WHERE 
    order1 = order2 
+0

merci pour l'alternative. Cela m'a aidé à comprendre ce que je cherchais (voir ma réponse). Je vais probablement essayer de voir si la perf est différente. –

Questions connexes