My quest might be answered in somewhere here but I couldn’t find. So, sorry if I asked in vain.
I have a Table that’s populate automatically with precisely date/time in SQL Server and looks like this:
Cod_Analise| Dat_analise | Nom_usuario| Resultado -----------+-----------------+------------+----------- 1 | 02/20/2019 14:30| John | 4.5 2 | 02/20/2019 14:31| Carl | 60 3 | 02/21/2019 17:25| Carl | 17 2 | 02/19/2019 06:00| Marcus | 58 1 | 02/20/2019 15:40| Jorge | 5.2 2 | 02/21/2019 22:00| John | 58
and I need something like this:
Dat_Analise | 1 | 2 | 3 | Nom_usuario ------------+---+---+---+------------ 02/19/2019 | 0 |58 | 0 | Marcus 02/20/2019 |4.9|60 | 0 | (First or Last one)
I need to do a pivot table based in this table where the Columns are Dat_Analise
(date), Nom_operador
(who did) and “Cod_Analise”(what did). And the rows are “Resultados”(results).
My problem is, i need to group by time period taking avg results for dynamic number of Cod_analises. But I even did the pivot with dynamic columns but I cannot fit the Group By part inside the pivot table.
I try to use a model that i found here and my procedure is like this:
SELECT A.[RESULTADO], A.[DAT_ANALISE], A.[NOM_USUARIO], B.[NOM_ANALISE] into #temporaria FROM [BSDB_Processo].[dbo].[RESULTADOS_ANALISES] A, [BSDB_Processo].[dbo].[ANALISES] B WHERE A.COD_PROCESSO = @PROCESSO AND A.COD_ANALISE = B.COD_ANALISE AND NUM_LOTE =@LOTE
Then:
declare @columnsSrc nvarchar(max) = N'' ,@columnsDst nvarchar(max) = N'' ,@sql nvarchar(max) ,@KeyColumns nvarchar(max) = N'DAT_ANALISE' ,@compatibility int = ( select top 1 compatibility_level from sys.databases where name = db_name() order by Name ); declare @GroupBy nvarchar(max) = --case when @compatibility <= 90 -- then case when len(@KeyColumns)=0 then '' else 'group by ' + @KeyColumns + -- ' with rollup' end -- else case when len(@KeyColumns)=0 then '' else 'group by rollup (' -- + @KeyColumns + ')' end -- end case when len(@KeyColumns)=0 then '' else 'group by ' + @KeyColumns end; select @columnsSrc += nchar(10) + N',' + quotename([NOM_ANALISE]) ,@columnsDst += nchar(10) + N',sum(isnull(' + quotename([NOM_ANALISE]) + N',0)) as ' + quotename([NOM_ANALISE]) from ( select [NOM_ANALISE] from #temporaria group by [NOM_ANALISE] ) as x order by x.[NOM_ANALISE]
And:
set @sql = N' select ' + case when len(@KeyColumns)=0 then '' else @KeyColumns + ',' end + STUFF(@columnsDst, 1, 2, '') + ' INTO ##tabelaAnalises from ( select' + nchar(10) + case when len(@KeyColumns)=0 then '' else @KeyColumns + ',' end + ' [NOM_ANALISE],[RESULTADO] from #temporaria ) as j pivot ( sum([RESULTADO]) for [NOM_ANALISE] in (' + stuff(replace(@columnsSrc, ',p.[', ',['), 2, 1, '') + ') ) as p' + nchar(10) + @GroupBy + ';' >; --print @sql; exec sp_executesql @sql; select * from ##tabelaAnalises commit End
Hope you can help me guys and ,again, sorry if i did something wrong with this post. First time using this
Advertisement
Answer
Try to see the below query. Please, see UPDATE section of a pivot with column Nom_usuario
.
Sample data:
IF OBJECT_ID('tempdb..#SomeTable') IS NOT NULL DROP TABLE #SomeTable GO CREATE TABLE #SomeTable ( Cod_Analise int, Dat_analise datetime, Nom_usuario varchar(50), Resultado numeric(18,1) ) INSERT INTO #SomeTable ( Cod_Analise, Dat_analise, Nom_usuario, Resultado ) VALUES ( 2, '20190219 06:00', 'Marcus', 58) , ( 1, '20190220 14:30', 'John', 4.5) , ( 2, '20190220 14:31', 'Carl', 60) , ( 1, '20190220 15:40', 'Jorge', 5.2) , ( 3, '20190221 17:25', 'Carl', 17) , ( 2, '20190221 22:00', 'John', 58)
A query:
SELECT pvt.Dat_analise , pvt.[1] , pvt.[2] , pvt.[3] FROM (SELECT CONVERT(date, (t.Dat_analise)) Dat_analise , t.Cod_Analise , t.Resultado FROM #SomeTable t) AS t PIVOT ( AVG(T.Resultado) FOR t.Cod_Analise IN ([1], [2], [3]) ) pvt
And dynamic version:
declare @cols nvarchar(max); declare @sql nvarchar(max); select @cols = stuff(( select distinct ' , ' + CONCAT('[', CONVERT(varchar(10), t.Cod_Analise), ']') from #SomeTable t order by 1 for xml path (''), type).value('.','nvarchar(max)') ,1,2,'') select @sql = ' select p.Dat_Analise,' + @cols + ' from ( SELECT CONVERT(date, (t.Dat_analise)) Dat_analise , t.Cod_Analise , t.Resultado FROM #SomeTable t ) as t pivot (AVG(T.Resultado) FOR t.Cod_Analise in (' + @cols + ') ) p' exec(@sql);
OUTPUT:
Dat_analise 1 2 3 2019-02-19 NULL 58.000000 NULL 2019-02-20 4.850000 60.000000 NULL 2019-02-21 NULL 58.000000 17.000000
UPDATE:
Use the following code snippet to show a Nom_usuario
:
declare @cols nvarchar(max); declare @sql nvarchar(max); select @cols = stuff(( select distinct ' , ' + CONCAT('[', CONVERT(varchar(10), t.Cod_Analise), ']') from SomeTable t order by 1 for xml path (''), type).value('.','nvarchar(max)') ,1,2,'') select @sql = ' select * from ( SELECT CONVERT(date, (t.Dat_analise)) Dat_analise , t.Cod_Analise , t.Resultado , MAX(t.Nom_usuario) OVER (PARTITION BY CONVERT(DATE, (t.Dat_analise))) Nom_usuario FROM SomeTable t ) as t pivot (AVG(T.Resultado) FOR t.Cod_Analise in (' + @cols + ') ) p' exec(@sql);
OUTPUT:
Dat_analise Nom_usuario 1 2 3 2019-02-21 John NULL 58.000000 17.000000 2019-02-20 Jorge 4.850000 60.000000 NULL 2019-02-19 Marcus NULL 58.000000 NULL