带有动态数据透视表

时间:2019-02-25 18:07:51

标签: sql sql-server

我的任务可能会在这里的某个地方得到回答,但我找不到。所以,对不起,如果我白白问了。

我有一个表,该表会在SQL Server中自动准确地填充日期/时间,如下所示:

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

我需要这样的东西:

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)

我需要基于此表创建数据透视表,其中的列为Dat_Analise(日期),Nom_operador(谁做了)和“ Cod_Analise”(做了什么)。并且这些行是“ Resultados”(结果)。

我的问题是,我需要按时间段分组,以平均结果得出Cod_analises的动态数量。但是我什至没有使用动态列进行数据透视,但是我无法将“分组依据”部分放入数据透视表中。

我尝试使用在这里找到的模型,过程如下:

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

然后:

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]    

并且:

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

希望您能帮助我,并且再次抱歉,如果我在这篇文章中做错了什么。第一次使用

1 个答案:

答案 0 :(得分:2)

尝试查看以下查询。请参阅带有列Nom_usuario的数据透视表的“更新”部分。

样本数据:

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)

查询:

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

动态版本:

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);

输出:

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

更新:

使用以下代码段显示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);

输出:

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