2016-03-22 19 views
6

So che ci sono diverse discussioni di applicazione non incrociata/incrociata qui ma non sono riuscito a trovare alcuna discussione che copra il mio problema. Quello che ho ottenuto finora è il seguente:TSQL Impossibile aprire più colonne con righe denominate?

SELECT Perc, Salary 
FROM (
    SELECT jobid, Salary_10 AS Perc10, Salary_25 AS Perc25, [Salary_Median] AS Median 
    FROM vCalculatedView 
    WHERE JobID = '1' 
    GROUP BY JobID, SourceID, Salary_10, Salary_25, [Salary_Median] 
) a 
UNPIVOT (
    Salary FOR Perc IN (Perc10, Perc25, Median) 
) AS calc1 

Ora, quello che vorrei è aggiungere diverse altre colonne, ad es. un nome Bonus che voglio anche mettere in Perc10, Perc25 e Median Rows.

In alternativa, ho anche effettuato una query con cross apply, ma qui sembra che non sia possibile forzare l'ordinamento delle righe come si può con unpivot. In altre parole, non posso avere un ordinamento personalizzato, ma solo un ordinamento che è secondo un numero all'interno della tabella, se sono corretto? Almeno, qui ottengo il risultato come vorrei, ma le righe sono nell'ordine sbagliato e non ho nomi di file come Perc10 ecc. Che sarebbe bello.

SELECT crossapplied.Salary, 
     crossapplied.Bonus 
FROM vCalculatedView v 
CROSS APPLY (
    VALUES 
      (Salary_10, Bonus_10) 
     , (Salary_25, Bonus_25) 
     , (Salary_Median, Bonus_Median) 
) crossapplied (Salary, Bonus) 
WHERE JobID = '1' 
GROUP BY crossapplied.Salary, 
     crossapplied.Bonus 

Perc sta per Percentile qui.

uscita è destinato ad essere qualcosa di simile:

+--------------+---------+-------+ 
| Calculation | Salary | Bonus | 
+--------------+---------+-------+ 
| Perc10  |  25 |  5 | 
| Perc25  |  35 | 10 | 
| Median  |  27 |  8 | 
+--------------+---------+-------+ 

mi manca qualcosa o fatto io qualcosa di sbagliato? Sto usando MSSQL 2014, l'output sta andando in SSRS. Grazie mille per qualsiasi suggerimento in anticipo!

Modifica di chiarimenti: L'UnPivot-Metodo dà il seguente risultato:

+--------------+---------+ 
    | Calculation | Salary | 
    +--------------+---------+ 
    | Perc10  |  25 | 
    | Perc25  |  35 | 
    | Median  |  27 | 
    +--------------+---------+ 

quindi manca la colonna "Bonus" qui.

Il Cross-Apply-Metodo dà il seguente risultato:

+---------+-------+ 
| Salary | Bonus | 
+---------+-------+ 
|  35 | 10 | 
|  25 |  5 | 
|  27 |  8 | 
+---------+-------+ 

Quindi, se lo si confronta con l'uscita prevista, si noterà che la colonna "Calcolo" è mancante e l'ordinamento riga è sbagliata (nota che la riga 25 | 5 si trova nella seconda riga anziché nella prima).

Modifica 2: definizione della vista e dati di esempio: La vista sostanzialmente aggiunge solo colonne calcolate della tabella. Nella tabella, ho colonne come stipendio e bonus per ogni JobID. La vista poi basta calcola i percentili in questo modo:

Select 
    Percentile_Cont(0.1) 
    within group (order by Salary) 
    over (partition by jobID) as Salary_10, 

    Percentile_Cont(0.25) 
    within group (order by Salary) 
    over (partition by jobID) as Salary_25 
from Tabelle 

Così la stampa ricorda:

+----+-------+---------+-----------+-----------+ 
| ID | JobID | Salary | Salary_10 | Salary_25 | 
+----+-------+---------+-----------+-----------+ 
| 1 |  1 |  100 |  60 |  70 | 
| 2 |  1 |  100 |  60 |  70 | 
| 3 |  2 |  150 |  88 |  130 | 
| 4 |  3 |  70 |  40 |  55 | 
+----+-------+---------+-----------+-----------+ 

Alla fine, la vista sarà parametrizzata in una stored procedure.

+1

vostro 'vCalculatedView' sembra fare i calcoli in anticipo ... Il vostro' by' gruppo non sta facendo niente ... Si prega di mostrare il risultato che si ottiene con la dichiarazione e fornire alcuni dati di esempio e l'output previsto. – Shnugo

+0

Il gruppo nel codice Cross Apply fa qualcosa: se non lo inserissi, Perc10, Perc25, Median si ripeterà più e più volte. Questo perché un ID lavoro non è l'ID dipendente e, in quanto tale, un ID lavoro può contenere più di un dipendente. – ksauter

+0

OK. Capisco cosa intendi. Potrebbe essere che un 'CTE' con un' SELECT DISTINCT' è ciò di cui hai piuttosto bisogno. 'GROUP BY' che useresti per aggregazioni come' MAX() 'o' SUM() 'Fornisci il risultato della tua query corrente e come dovrebbero essere visualizzati i tuoi dati. – Shnugo

risposta

1

Potrebbe essere il tuo approccio?

Dopo le modifiche, capisco che la soluzione con CROSS APPLY ritorna con i dati corretti, ma non con l'output corretto. È possibile aggiungere valori costanti al vostro VALUES e fare l'ordinamento in un involucro SELECT:

SELECT wrapped.Calculation, 
     wrapped.Salary, 
     wrapped.Bonus 
FROM 
(
    SELECT crossapplied.* 
    FROM vCalculatedView v 
    CROSS APPLY (
     VALUES 
       (1,'Perc10',Salary_10, Bonus_10) 
      , (2,'Perc25',Salary_25, Bonus_25) 
      , (3,'Median',Salary_Median, Bonus_Median) 
    ) crossapplied (SortOrder,Calculation,Salary, Bonus) 
    WHERE JobID = '1' 
    GROUP BY crossapplied.SortOrder, 
      crossapplied.Calculation, 
      crossapplied.Salary, 
      crossapplied.Bonus 
) AS wrapped 
ORDER BY wrapped.SortOrder 
+0

Grazie! Ho contrassegnato la tua soluzione come corretta. Tuttavia, per gli altri lettori, è necessario inserire tutte le colonne (SortOrder, Calculation, Stipendio, Bonus) nella clausola GROUP BY, non solo Salary e Bonus. La scorsa notte, ho scritto la query con il metodo UNPIVOT con CTE e LEFT JOIN, ma questo è ovviamente un codice molto più lungo. Per i lettori che verranno, inserirò questo come un'altra risposta, ma non è per battere la tua soluzione. Le tue soluzioni mostrano ancora una volta che la maggior parte delle volte, CROSS APPLY batte Unpivot proprio come numerosi blogger mostrano nei confronti. – ksauter

+1

Thx per l'accettazione! Ho modificato la mia risposta per riflettere il tuo suggerimento su "GROUP BY COLUMNS". Se ti piace la mia risposta sarebbe gentilmente di votare in più. La votazione e l'accettazione sono due passi separati ... Grazie ancora! – Shnugo