2013-06-12 24 views
19

Ho due tabelle con i datiSQL server uniscono tavoli e perno

TABELLA 1

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

TABELLA 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  | 

Ho bisogno di una domanda che produrrà

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 

io sono abbastanza nuovo a rotazione e non è sicuro se perno è modo di andare per questo o no.

+1

Quante categorie ci sono? Questa è la lista completa? Potrebbero esserci di più in futuro? – ErikE

+0

Ci sono circa 7 categorie. Non andare oltre. –

risposta

35

Questo dovrebbe funzionare:

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 
; 

Oppure alternativamente:

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 
; 

Questi hanno la stessa di risultati e possono in effetti essere trattati allo stesso da Query Optimizer, ma forse non. La grande differenza entra in gioco quando si iniziano a mettere le condizioni sulla tabella Sale - si dovrebbe testare e vedere quale query funziona meglio.

Posso suggerire, tuttavia, di eseguire il pivot nel livello di presentazione? Se, ad esempio, si utilizza SSRS, è abbastanza semplice utilizzare un controllo matrix che eseguirà tutte le operazioni di rotazione. È meglio, perché se aggiungi un nuovo Category, non avrai modificato tutto il tuo codice SQL!

C'è un modo per trovare dinamicamente i nomi delle colonne su pivot, ma implica l'SQL dinamico. Non lo consiglio davvero come il modo migliore, anche se è possibile.

Un altro modo che potrebbe lavoro sarebbe quello di pre-elaborare la query - significa impostare un trigger nella tabella Category che riscrive un VIEW per contenere tutte le categorie esistenti che esistono. Questo risolve molti degli altri problemi che ho menzionato, ma ancora una volta, usare il livello di presentazione è il migliore.

Nota: Se i nomi di colonna (che erano precedentemente valori) sono numeri o iniziano con un numero, è necessario citare con parentesi quadre come in PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P. In alternativa, è possibile modificare i valori prima che raggiungano la parte PIVOT della query per anteporre alcune lettere, in modo che l'elenco di colonne non necessiti l'escape. Per ulteriori informazioni su questo, consultare le regole per gli identificatori in SQL Server.

+0

Grazie davvero utile .... prima query lavorato, nella query forst Pls aggiunge 'I' dopo INNER JOIN dbo.SaleItem O INNER JOIN dbo.SaleItem ho Grazie –

+0

Assicurati di esaminare se 'Max()' è appropriato - se potrebbe esserci più di uno per SaleID + Categoria, potrebbe essere necessario 'Sum()', o qualche tipo di calcolo preliminare 'Row_Number()' in modo che i valori possano essere su righe separate. – ErikE