【问题标题】:Dynamic Pivot SQL with multiple aggregations具有多个聚合的动态 Pivot SQL
【发布时间】:2019-02-27 17:13:01
【问题描述】:

我有一个查询,它通过列的动态列表(即列可以随时更改)并透视显示这些列的最大安装日期的数据。但是,我的问题是,我如何进行多个聚合?我也需要每个 PlaceRef 的 Max LocationCode、MakeCode 和 ModelCode,但我正在努力做到这一点。非常感谢。

    DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(Component ) 
  FROM (SELECT p.Component FROM VwLocationComponentCurrent AS p
    INNER JOIN VwLocationListEntriesCurrent AS o ON p.PlaceRef = o.PlaceRef
    where o.LocationList = N'NEWBUILD'
    GROUP BY p.Component) AS x;



SET @sql = N'
SELECT PlaceRef, Address1, StreetName, PostCode, Substatus, BuildingType, BuildDate, ' + STUFF(@columns , 1, 2, '') + '
FROM
(
  SELECT 
  vwLocationCurrent.PlaceRef
  ,vwLocationCurrent.BuildDate
  ,vwLocationCurrent.SubStatus
  ,vwLocationCurrent.StreetName
  ,vwLocationCurrent.Address1
  ,vwLocationCurrent.Address2
  ,vwLocationCurrent.Address3
  ,vwLocationCurrent.PostCode
  ,VwLocationComponentCurrent.Component
  ,VwLocationComponentCurrent.SubLocationCode
  ,VwLocationComponentCurrent.InstalledDate
  ,VwLocationComponentCurrent.MakeCode
  ,VwLocationComponentCurrent.ModelCode
  ,VwLocationListEntriesCurrent.LocationList
  ,vwLocationCurrent.BuildingType

FROM
  vwLocationCurrent
  INNER JOIN VwLocationListEntriesCurrent
    ON vwLocationCurrent.PlaceRef = VwLocationListEntriesCurrent.PlaceRef
  LEFT OUTER JOIN VwLocationComponentCurrent
    ON vwLocationCurrent.PlaceRef = VwLocationComponentCurrent.PlaceRef
    WHERE
VwLocationListEntriesCurrent.LocationList = ''NEWBUILD''
) AS j

PIVOT
(
  MAX(InstalledDate) FOR Component IN ('
  + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
  + ')
) AS p;'
;
PRINT @sql;
EXEC sp_executesql @sql;

【问题讨论】:

  • 您使用的是哪个 dbms? (该查询是特定于产品的。)
  • @Deb 如果有人问您数据库是什么,请将该数据库添加为标签(我刚刚做了)。标签很重要。
  • 好的,谢谢,我已经把 SQL 放在标签里了,只是没有 SQL-Server,干杯。
  • 对于多重聚合,使用MAX(CASE WHEN ... END)的方式更方便
  • 不确定是否可以使用 MAX(CASE WHEN .. ),因为列名是动态创建的,并且随时都有超过 50 个

标签: sql sql-server dynamic pivot


【解决方案1】:

我建议您不要在此处使用“数据透视”功能,而是使用采用“条件聚合”的旧技术。这意味着“列”字符串的创建更加复杂,但它确实允许您在单个查询中输出多个聚合。以下代码未经测试,因为没有可使用的示例数据:

DECLARE @columns nvarchar(max)
      , @sql nvarchar(max);
SET @columns = N'';
SELECT
       @columns +=
     + N', max(case when Component = p.' + QUOTENAME(Component) + N' then SubLocationCode end) as ' + QUOTENAME('Loc_' + Component)
     + N', max(case when Component = p.' + QUOTENAME(Component) + N' then MakeCode end) as ' + QUOTENAME('Mak_' + Component)
     + N', max(case when Component = p.' + QUOTENAME(Component) + N' then ModelCode end) as '+  QUOTENAME('Mod_' + Component)
FROM (
    SELECT
        p.Component
    FROM VwLocationComponentCurrent AS p
    INNER JOIN VwLocationListEntriesCurrent AS o ON p.PlaceRef = o.PlaceRef
    WHERE o.LocationList = N'NEWBUILD'
    GROUP BY
        p.Component
) AS x;

SET @sql = N'
SELECT PlaceRef, Address1, StreetName, PostCode, SubStatus, BuildingType, BuildDate, ' + STUFF(@columns, 1, 2, '') + '
FROM
(
  SELECT 
   vwLocationCurrent.PlaceRef
  ,vwLocationCurrent.Address1
  ,vwLocationCurrent.StreetName
  ,vwLocationCurrent.PostCode
  ,vwLocationCurrent.SubStatus
  ,vwLocationCurrent.BuildingType
  ,vwLocationCurrent.BuildDate'
+ STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
+ N' FROM vwLocationCurrent
  INNER JOIN VwLocationListEntriesCurrent
    ON vwLocationCurrent.PlaceRef = VwLocationListEntriesCurrent.PlaceRef
  LEFT OUTER JOIN VwLocationComponentCurrent
    ON vwLocationCurrent.PlaceRef = VwLocationComponentCurrent.PlaceRef
  WHERE VwLocationListEntriesCurrent.LocationList = ''NEWBUILD''
  GROUP BY
   vwLocationCurrent.PlaceRef
  ,vwLocationCurrent.Address1
  ,vwLocationCurrent.StreetName
  ,vwLocationCurrent.PostCode
  ,vwLocationCurrent.SubStatus
  ,vwLocationCurrent.BuildingType
) AS p;'
;
PRINT @sql;
EXEC sp_executesql @sql;

【讨论】:

  • 谢谢,只是想理解它,但当我尝试运行它时,出现以下错误:Msg 102, Level 15, State 1, Line 12 Incorrect syntax near '('.
猜你喜欢
  • 1970-01-01
  • 2016-10-04
  • 2014-11-27
  • 2010-11-17
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 2018-06-28
  • 2016-10-16
相关资源
最近更新 更多