SQL查询将2个表中的数据与数据透视组合

Posted

技术标签:

【中文标题】SQL查询将2个表中的数据与数据透视组合【英文标题】:SQL query to combine data from 2 tables with pivot 【发布时间】:2017-11-16 03:29:55 【问题描述】:

我有 2 张桌子:

CREATE TABLE [ObIndex](
    [idx] [int] IDENTITY(1,1) NOT NULL,
    [dtg] [smalldatetime] NOT NULL,
    [site] [varchar](6) NOT NULL,
    [name] [varchar](32) NOT NULL,
    [lat] [float] NOT NULL,
    [lon] [float] NOT NULL,
    [el] [int] NOT NULL,
 CONSTRAINT [PK_SurfaceObIndex] PRIMARY KEY CLUSTERED 
(
    [icao] ASC,
    [dtg] ASC
)

CREATE TABLE [ObData](
    [idx] [int] NOT NULL,
    [label] [varchar](32) NOT NULL,
    [value] [varchar](128) NOT NULL,
 CONSTRAINT [PK_SurfaceObData] PRIMARY KEY CLUSTERED 
(
    [idx] ASC,
    [label] ASC
)

对于 ObIndex 中的每条记录,ObData 中将存在一个或多个记录,每个记录都包含来自观测的单个参数(请注意,站可能有不同的仪器):

ObIndex (metadata)
    1,"2017-11-15 12:00:00","C104","AWS 104",-77.100,-167.100,33
    2,"2017-11-15 12:00:00","C105","AWS 105",-77.200,-167.200,55
    etc.

ObData (instrument data)
    1,"Temperature", -10
    1,"DewPoint", -20
    1,"WindDirection", 123
    1,"WindSpeed", 45
    1,"Humidity",66
    2,"Temperature", -10
    2,"DewPoint", -20
    2,"WindDirection", 123
    2,"WindSpeed", 45
    2,"Pressure",998
    etc.

还有与此问题无关的当前站点位置的第三个表。

如果可能,我想使用单个查询从 ObData 表中提取每个 ObIndex 记录的所有值,并将“标签”值转换为列名。此查询适用于单个观察(或 ObIndex 中的记录):

select
Min(Case label When 'Temperature' Then value End) Temperature, 
Min(Case label When 'DewPoint' Then value End) DewPoint
Min(Case label When 'WindSpeed' Then value End) WindSpeed, 
Min(Case label When 'WindDirection' Then value End) WindDirection, 
From SurfaceObData Where SurfaceObData.idx = 138586

谁能帮我完成查询以返回所有观察的数据? 理想情况下,结果如下所示:

idx,site,dtg,WindDirection,WindSpeed,Temperature,Humidity,Dewpoint,Pressure
1,"C104",2017-11-15 12:00:00,123,45,-10,66,-20,
2,"C106",2017-11-15 12:00:00,123,45,-10,,-20,998

(不知道如何把它放在表格格式中......第一次发帖。)

提前致谢!

【问题讨论】:

【参考方案1】:

只需按SurfaceObData.idx 列分组

select SurfaceObData.idx,
       Min(Case label When 'Temperature' Then value End) Temperature, 
       Min(Case label When 'DewPoint' Then value End) DewPoint
       Min(Case label When 'WindSpeed' Then value End) WindSpeed, 
       Min(Case label When 'WindDirection' Then value End) WindDirection, 
From   SurfaceObData
Group By SurfaceObData.idx

【讨论】:

太棒了!谢谢!如此简单......但是,我可以看到我没有明确表示我也想从观察中获得元数据(至少是站点和日期)。 预期结果如何? 顺便说一句,我给了你的答案+1,但由于我的地位低,它没有显示出来。再次感谢! 没关系。不用担心。【参考方案2】:

感谢松鼠的帮助,我找到了解决方案:

select i.idx,i.site,i.dtg,
    Min(Case d.label When 'WindDirection' Then d.value End) WindDirection, 
    Min(Case d.label When 'WindSpeed' Then d.value End) WindSpeedKnots, 
    Min(Case d.label When 'Temperature' Then d.value End) Temperature, 
    Min(Case d.label When 'Humidity' Then d.value End) Humidity,
    Min(Case d.label When 'DewPoint' Then d.value End) DewPoint,
    Min(Case d.label When 'Pressure' Then d.value End) Pressure
    from SurfaceObData  as d, SurfaceObIndex as i 
    where d.idx = i.idx
    group by i.idx,i.site,i.dtg

【讨论】:

以上是关于SQL查询将2个表中的数据与数据透视组合的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询某字段数据所在的表

没有聚合函数的 SQL Server 数据透视查询

将数据透视结果附加(插入)到现有 SQL 表中

Google BigQuery 中的多级数据透视

SQL Server 中具有动态列的数据透视表

用于从 VIEW 表中提取数据的 SQL 透视查询