Query che recepisce alcune righe in nomi delle colonne
-
06-09-2019 - |
Domanda
Ho un paio di tavoli che simile a questa Tabella 1
user_id | name
-------------------------
x111 | Smith, James
x112 | Smith, Jane
etc ..
Tabella 2
id | code | date | incident_code | user_id
-----------------------------------------------------------------
1 | 102008 | 10/20/2008 | 1 | x111
2 | 113008 | 11/30/2008 | 3 | x111
3 | 102008 | 10/20/2008 | 2 | x112
4 | 113008 | 11/30/2008 | 5 | x112
Quello che mi piacerebbe per visualizzare è qualcosa di simile
user_id | user_name | INCIDENT IN OCT 2008 | INCIDENT IN NOV 2008
------------------------------------------------------------------------------
x111 | Smith, John | 1 | 3
x112 | Smith, Jane | 2 | 5
etc ..
L'incident_code sarebbe sostituito dalla descrizione attuale dell'incidente che si trova in un altro tavolo, ma ho pensato di vedere come avrebbe funzionato prima.
Alcune delle intestazioni delle colonne sarebbe statico, mentre altri sarebbero stati creati in base alla data. Qualcuno si sa come posso farlo utilizzando sql server 2005? Alcuni esempi sarebbe molto utile.
Grazie in anticipo
Soluzione
Ecco una soluzione che genera e gestisce lo SQL dinamico con un perno:
DECLARE @pivot_list AS VARCHAR(MAX)
--
;
WITH cols
AS ( SELECT DISTINCT
'INCIDENT IN ' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)),
3) + ' '
+ SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
FROM so926209_2
)
SELECT @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + col + ']'
FROM cols
--
DECLARE @template AS VARCHAR(MAX)
SET @template = 'WITH incidents AS (
SELECT [user_id],
incident_code,
''INCIDENT IN '' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)), 3)
+ '' '' + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
FROM so926209_2
)
,results AS (
SELECT * FROM incidents PIVOT (MAX(incident_code) FOR col IN ({@pivot_list})) AS pvt
)
SELECT results.[user_id]
,so926209_1.[name]
,{@select_list}
FROM results INNER JOIN so926209_1 ON so926209_1.[user_id] = results.[user_id]
'
DECLARE @sql AS VARCHAR(MAX)
SET @sql = REPLACE(REPLACE(@template, '{@pivot_list}', @pivot_list), '{@select_list}', @pivot_list)
--PRINT @sql
EXEC (@sql)
Dove so926209_1
, so926209_2
sono la vostra tabella 1 e la tabella 2
Si noti che se si dispone di più incidenti in un mese per la stessa persona, il tuo esempio non mostra come si desidera che ha gestito. Questo esempio richiede solo l'ultimo incidente nel mese.
Altri suggerimenti
Si vuole Pivot http://msdn.microsoft.com/en-us/library/ms177410. aspx
Questo suona come un compito di reporting. Segnalazione, spesso definito da una prospettiva database OLAP, linea Aanalytical Processing, tende a differire abbastanza frequentemente da "tradizionale" accesso al database, OLTP (Online Transaction Processing) dal fatto che è spesso costituito da grandi aggregazioni di dati che coprono maggiori periodi di tempo. Molto spesso, il tipo di aggregazione vostro ricerca.
L'uso di un pivot come tetraneutrone suggerito sarà sufficiente per i set di dati più piccoli. Tuttavia, come il volume dei dati è necessario riferire in merito cresce, potrebbe essere necessario qualcosa di più avanzato. OLAP sia previsto da SQL Server Analysis Services (SSAS), disponibili nel 2005 e nel 2008. Usando SSAS è possibile creare archivi di dati multidimensionali che i dati pre-aggregati sia da un database OLTP direttamente, o da un database del data warehouse intermediario. dati multidimensionali (di solito denominato cubi), forniscono un modo molto più veloce per accedere al tipo di dati che si può ottenere da un pivot, senza interferire con le prestazioni del vostro elaborazione delle transazioni di serie nel database OLTP.
Se si dispone di più di una piccola quantità di dati è necessario riferire in merito, vi consiglio di controllare SQL Server Analysis Services 2005, OLAP, cubi, e MDX (Multidimensional Estensioni per T-SQL.) C'è un learnig più grande curva di istituire un cubo OLAP, ma una volta che è installato, i vantaggi di avere uno può essere enorme se si dispone di notevoli esigenze di reporting.
Una query come questo dovrebbe funzionare:
select
u.User_id,
u.Name,
Okt2008Sum = sum(case when i.date between
'2008-10-01' and '2008-11-01' then 1 else 0 end),
Nov2008Sum = sum(case when i.date between
'2008-11-01' and '2008-12-01'then 1 else 0 end)
from #incidents i
inner join #users u on i.user_id = u.user_id
group by u.user_id, u.name
A seconda del cliente e con quale frequenza si deve eseguire, è possibile generare questa query. In SQL questo sarà simile:
create table #months (
MonthName varchar(25),
StartDate datetime
)
insert into #months values ('Okt2008','2008-10-01')
insert into #months values ('Nov2008','2008-11-01')
declare @query varchar(8000)
select @query = 'select u.User_id, u.Name '
select @query = @query + ', ' + MonthName +
' = sum(case when i.date between ''' + cast(StartDate as varchar) +
''' and ''' + cast(dateadd(m,1,StartDate) as varchar) +
''' then 1 else 0 end) '
from #Months
select @query = @query + '
from #incidents i
inner join #users u on i.user_id = u.user_id
group by u.user_id, u.name'
exec (@query)