帮助加入查询和返回限制

时间:2011-02-24 19:48:15

标签: mysql sql join greatest-n-per-group

我的数据库中有两个表 - gl_weather_locations和gl_weather_data。

location table location records data table data records

我需要从位置表中选择位置名称,纬度和经度,然后只获取数据表中相应lat / long的最新记录集 - 可以有多个集合,因为数据库是从每2小时更新一次的Web服务。我们需要保存档案数据,因此我们不能只保留最新的记录集,我们需要保留所有这些记录。但是我有点困惑如何将我的查询限制到最近的一组(每个位置有3个数据记录的倍数 - 一个用于风速,一个用于风向,一个用于波高 - 我们需要获得最近的三个。)

到目前为止我所拥有的是:

SELECT l.location_name, l.location_lat, l.location_long, d.weather_type, 
       d.weather_value, d.weather_unit
FROM gl_weather_locations l
LEFT JOIN gl_weather_data d ON l.location_lat = d.weather_lat

(在我们的例子中,我们正在使用有限数量的地点,并且绝对确认我们没有多个位置具有完全相同的纬度,因此我们可以安全地仅在纬度上进行连接,而不是而不是需要比较经度。)

我很困惑,我怎么能确保我只获得每个纬度的最新记录集。如果有帮助,对于集合中的所有记录,weather_time字段是相同的(即,我们有10个位置,每个Web服务运行每个位置3个记录,因此我们在weather_time中有30个具有相同值的记录。)我能不知何故是按顺序使用,还是按组合使用?

2 个答案:

答案 0 :(得分:2)

第二个FROM(通过SQL-Select)可以让你获得每个纬度/长度,每个类别的最大相应时间。然后,整体查询将位置链接到该(MaxTimes)别名,然后基于与要测试的相应分类单元匹配的最大时间重新连接到天气数据。如果你得到任何NULL值,你可以将这些列包装为NVL(whatever_column,'')作为ResultColumn

select WLoc.ID,
       WLoc.Location_Name,
       WLoc.Location_Lat,
       WLoc.Location_Long,
       IFNULL( MaxTimes.WindDirTime, '' ) WindDirTime,       
       IFNULL( MaxTimes.WindSpdTime, '' ) WindSpdTime,       
       IFNULL( MaxTimes.WaveHeightTime, '' ) WaveHeightTime,       
       IFNULL( ByWindDir.Weather_Unit, '' ) WindDirection,       
       IFNULL( ByWindDir.Weather_Value, '' ) WindDirValue,       
       IFNULL( ByWindSpd.Weather_Unit, '' )  SpeedUnit,       
       IFNULL( ByWindSpd.Weather_Value, '' )  WindSpeed,       
       IFNULL( ByWaveHeight.Weather_Unit, '' )  WaveUnit,       
       IFNULL( ByWaveHeight.Weather_Value, '' )  WaveHeight
  from
     gl_weather_locations WLoc
        left join (select weather_lat,
                          weather_long,
                          max( case when weather_type = "Wind Direction" then weather_time end ) WindDirTime,
                          max( case when weather_type = "Wind Speed" then weather_time end ) WindSpdTime,
                          max( case when weather_type = "Wave Height" then weather_time end ) WaveHeightTime
                      from
                          gl_weather_data
                      group by 
                          1, 2 ) MaxTimes
             on WLoc.Location_Lat = MaxTimes.Weather_Lat
            and WLoc.Location_Long = MaxTimes.Weather_Long

                 left join gl_weather_data ByWindDir
                    on MaxTimes.weather_lat = ByWindDir.weather_lat
                    and MaxTimes.weather_long = ByWindDir.weather_long
                    and MaxTimes.WindDirTime = ByWindDir.weather_time
                    and ByWindDir.weather_type = "Wind Direction"

                 left join gl_weather_data ByWindSpd
                    on MaxTimes.weather_lat = ByWindSpd.weather_lat
                    and MaxTimes.weather_long = ByWindSpd.weather_long
                    and MaxTimes.WindSpdTime = ByWindSpd.weather_time
                    and ByWindSpd.weather_type = "Wind Speed"

                 left join gl_weather_data ByWaveHeight
                    on MaxTimes.weather_lat = ByWaveHeight.weather_lat
                    and MaxTimes.weather_long = ByWaveHeight.weather_long
                    and MaxTimes.WaveHeightTime = ByWaveHeight.weather_time
                    and ByWaveHeight.weather_type = "Wave Height"

第一个FROM表是你的主要位置列表...通过LEFT JOIN,你告诉SQL,无论我在右侧是否有时间戳匹配,向我显示所有位置。

接下来,是MaxTimes的PreQuery。可以将此子查询视为预先收集每个纬度/长度的最大时间,通过MAX报告的PER各自的测量类型(情况......)作为FinalColumnName。因此,在每条记录上,它只能获得其中一个案例条目,如果找到,则获得该列时间的最大值。

所以,现在,你有一个位置列表,并加入了各自LAT / LONG加入的子查询MaxTimes。现在,MaxTimes查询分别对每个测量进行三次左连接回测量数据,因此我将它们的目的所在的别名...因此ByWindDir,ByWindSpd和ByWaveHeight。与其他连接一样,左连接分别基于Lat / Long,其正确类型(“风向”,“风速”或“波浪高度”),并且它与该类别具有相同的匹配时间。

这个查询的好处在于,如果你的时间到一个纬度/长度的位置都是关闭的,即使是秒(即风向是11:58:02,风速是11:58:05和波浪高度= 11:58:54,它仍将尊重每个唯一测量的最大时间。

最后,字段列表......为了解决所有问题,我得到了明显的细节......由于每个表都被加入来代表它自己的“东西”,我的列名代表了背景...希望这有助于您理解这个问题......一次只做一个部分,找到与之相关的链接。

答案 1 :(得分:0)

尝试:

SELECT l.location_name, l.location_lat, l.location_long, 
       d.weather_type, d.weather_value, d.weather_unit FROM gl_weather_locations l 
LEFT JOIN gl_weather_data d on l.location_lat = d.weather_lat 
**order by weather_time desc limit 3**