2013-06-12 14 views
19

że dwie tabele z danymiserwer SQL łączenia tabel i czop

TABELA 1

--------------------------------------------------- 
    | SALEID | SOLDBY | SALEPRICE | MARGIN | DATE | 
    | 1  | 'aa' | 10,000 | 10 | 2013-1-1 | 
    | 2  | 'bb' | 25,000 | 5 | 2013-5-1 | 

Tabela 2

--------------------------------------------------- 
    | SALEITEMID | SALEID | SALEPRICE | CATEGORY | 
    | 1   | 1  | 6,000 | BOOKS | 
    | 2   | 1  | 4,000 | PRINTING | 
    | 3   | 2  | 5,000 | BOOKS | 
    | 4   | 2  | 12,000 | PRINTING | 
    | 5   | 2  | 8,000 | DVD  | 

potrzebne zapytania, które spowoduje

tab3

-------------------------------------------------------------------------------- 
    | SALEID | SOLDBY | SALEPRICE | MARGIN | DATE | BOOKS | PRINTING | DVD 
    | 1  | 'aa' | 10,000 | 10 | 2013-1-1 | 6,000 | 4,000 | 0 
    | 2  | 'bb' | 25,000 | 5 | 2013-5-1 | 5,000 | 12,000 | 8,000 

Jestem całkiem nowy, przechylania i nie wiem, czy oś jest droga do tego, czy nie.

+1

Ile jest tam kategorii? Czy to pełna lista? Czy może być więcej w przyszłości? – ErikE

+0

Istnieje około 7 kategorii. Nie przekraczaj tego. –

Odpowiedz

35

To powinno działać:

WITH Sales AS (
    SELECT 
     S.SaleID, 
     S.SoldBy, 
     S.SalePrice, 
     S.Margin, 
     S.Date, 
     I.SalePrice, 
     I.Category 
    FROM 
     dbo.Sale S 
     INNER JOIN dbo.SaleItem I 
     ON S.SaleID = I.SaleID 
) 
SELECT * 
FROM 
    Sales 
    PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P 
; 

lub na przemian:

SELECT 
    S.SaleID, 
    S.SoldBy, 
    S.SalePrice, 
    S.Margin, 
    S.Date, 
    I.Books, 
    I.Printing, 
    I.DVD 
FROM 
    dbo.Sale S 
    INNER JOIN (
     SELECT * 
     FROM 
     (SELECT SaleID, SalePrice, Category FROM dbo.SaleItem) I 
     PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P 
    ) I ON S.SaleID = I.SaleID 
; 

one mają taką samą resultset i może w rzeczywistości być traktowane tak samo przez optymalizator zapytań, ale być może nie. Duża różnica zaczyna działać, gdy zaczynasz stawiać warunki na tabeli Sale - powinieneś przetestować i zobaczyć, które zapytanie działa lepiej.

Czy mogę jednak zasugerować, aby wykonać obracanie w warstwie prezentacji? Jeśli, na przykład, korzystasz z SSRS, całkiem łatwo jest użyć kontrolki macierzy, która wykona dla ciebie wszystkie obroty. To jest najlepsze, ponieważ jeśli dodasz nową Category, nie zmodyfikujesz całego kodu SQL!

Istnieje sposób na dynamiczne znajdowanie nazw kolumn do przestawiania, ale wymaga to dynamicznego SQL. Naprawdę nie polecam tego jako najlepszego, chociaż jest to możliwe.

Innym sposobem, który mógłbypraca byłoby Preprocesuj tej kwerendy - Pojęcie ustawić spust na stole Category który zmienia bieg VIEW zawierać wszystkie ocalałe kategorie, które istnieją. To rozwiązuje wiele innych problemów, o których wspomniałem, ale znowu, najlepiej jest użyć warstwy prezentacji.

Uwaga: Jeśli nazwy kolumn (które były poprzednio wartości) są liczbami lub rozpocząć z numerem, należy przytoczyć je w nawiasach kwadratowych jak PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P. Alternatywnie, możesz zmodyfikować wartości, zanim dotrą one do części zapytania, aby poprzedzić niektóre litery, aby lista kolumn nie wymagała ucieczki. W celu uzyskania dalszych informacji na ten temat sprawdź zasady dla identyfikatorów w SQL Server.

+0

Dzięki Naprawdę pomocny .... pierwsze zapytanie pracował w zapytaniu forst Pls dodać 'ja' po INNER JOIN dbo.SaleItem LUB INNER JOIN dbo.SaleItem I Dzięki –

+0

Upewnij się zbadać, czy 'Max()' jest odpowiednie - jeśli może być więcej niż jeden na kategorię SaleID +, może być potrzebne 'Sum()' lub jakiś rodzaj wstępnego obliczenia 'Row_Number()', więc wartości mogą być w osobnych wierszach. – ErikE