SQL 枢轴 - 城镇名称天气

SQL Pivot - Weather by Town Name

我正在收集 3 个州的六个城镇的天气数据。我主要感兴趣的是这个练习的温度和气压。我想要做的是将基本关系 table 转换为类似于以下内容的报告:

Date/Time Firestone Temp Firestone Pressure Sedalia Temp Sedalia Pressure etc... etc...
2021-11-09 08:30:00 31.16 2019 40.65 2021 etc... etc...
2021-11-09 09:00:00 31.16 2019 40.65 2021 etc... etc...

T-SQL tables(重要)看起来像:

CREATE TABLE [dbo].[WeatherResponse](
    [WeatherResponseId] [uniqueidentifier] NOT NULL,
    [Base] [varchar](255) NULL,
    [Visibility] [int] NULL,
    [Dt] [int] NULL,
    [Timezone] [int] NULL,
    [Name] [varchar](255) NULL,
    [Id] [int] NOT NULL,
    [Created] [datetime2](7) NOT NULL,
 CONSTRAINT [PK_WeatherResponse] PRIMARY KEY CLUSTERED 
(
    [WeatherResponseId] ASC
)

CREATE TABLE [dbo].[Mains](
    [Id] [int] NOT NULL,
    [WeatherResponseId] [uniqueidentifier] NOT NULL,
    [Temp] [float] NOT NULL,
    [FeelsLike] [float] NOT NULL,
    [TempMin] [float] NOT NULL,
    [TempMax] [float] NOT NULL,
    [Pressure] [int] NOT NULL,
    [Humidity] [int] NOT NULL,
    [SeaLevel] [int] NOT NULL,
    [GrndLevel] [int] NOT NULL,
    [Created] [datetime2](7) NOT NULL,
 CONSTRAINT [PK_Mains] PRIMARY KEY CLUSTERED 
(
    [Id] ASC,
    [WeatherResponseId] ASC
)

然而,我的支点没有产生预期的结果。可能是因为我在深夜工作时被菜鸟错误绊倒了! ;)
注意:我目前只处理 TEMP,但最后需要两列数据。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME([Name]) 
                    from WeatherResponse
                    group by [Name]
                    order by ',' + QUOTENAME([Name])
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT Created, Temp,' + @cols + ' from 
             (
                select r.Created, ((w.Temp-273.35) * (9/5)) + 32 as Temp, r.Name
                  from WeatherResponse r inner join Mains w on w.WeatherResponseId = r.WeatherResponseId
            ) x
            pivot 
            (
                max(Name)
                for Name in (' + @cols + ')
            ) p '

execute(@query)

结果看起来更像:

Date/Time Firestone Temp Firestone Pressure Sedalia Temp Sedalia Pressure etc... etc...
2021-11-09 08:30:00 null null Sedalia Sedalia etc... etc...
2021-11-09 09:00:00 null null Sedalia Sedalia etc... etc...
2021-11-09 08:30:00 Firestone Firestone null null etc... etc...
2021-11-09 09:00:00 Firestone Firestone null null etc... etc...

所以,请有人用 的那一刻打我一巴掌。我需要一些咖啡因。

编辑:在 SQL Mangler 中添加了结果照片...

如前所述,T-SQL 不支持具有多个聚合函数的 pivot,因此您可以使用条件聚合来实现相同的功能。只要您生成代码并且不需要手动输入代码,一个可能的缺点就是结果查询的大小。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

;select @cols = STUFF((
  SELECT DISTINCT
    replace(replace(replace(
      ', max(iif([Name]=val, [Temp], null)) as coltemp, max(iif([Name] = val, [Pressure], null)) as colpres
'
      /*Substitute quoted value string*/
      , 'val', quotename([Name], '''')
      )
      /*Substitute temperature column name*/
      , 'coltemp', QUOTENAME([Name] + ' temp')
      )
      /*Substitute pressure column name*/
      , 'colpres', quotename([Name] + ' pressure')
      )
  from WeatherResponse
  group by [Name]
  FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1,1,'')

;set @query = '
SELECT Created
,' + @cols + '
from (
  select
    r.Created
    , ((w.Temp-273.35) * (9/5)) + 32 as Temp
    , pressure
    , r.Name
  from WeatherResponse r
    inner join Mains w
      on w.WeatherResponseId = r.WeatherResponseId
) as x
group by created'

;execute( @query)
GO
Created                     | Firestone temp | Firestone pressure | Sedalia temp | Sedalia pressure
:-------------------------- | -------------: | -----------------: | -----------: | ---------------:
2021-11-16 17:12:48.1233333 |        -231.35 |                100 |      -221.35 |              300

db<>fiddle here

关于您的原始问题:正如我所说,[Temp] 列在结果集中不可用,它是由 pivot.

聚合的

附带说明:在准备最小可重现示例时,请不要在 table 定义中包含太多未使用的 not null 列。它们无助于插入一些示例数据,这对于动态查询至关重要。