Помощь с запросом на присоединение и лимитом возврата - PullRequest
2 голосов
/ 24 февраля 2011

В моей базе данных есть две таблицы - gl_weather_locations и gl_weather_data.

location table location records data table data records

Мне нужно выбрать имя местоположения, широту и долготу из таблицы местоположений, а затем получить только самый последний набор записей для соответствующего широты / длины в таблице данных - их может быть несколько, поскольку база данных заполняется веб-сервис, который обновляется каждые 2 часа. Нам нужно хранить архивные данные, поэтому мы не можем хранить только самые последние наборы записей, нам нужно хранить их все. Но меня немного смущает вопрос о том, как ограничить свой запрос только самым последним набором (для каждого местоположения существует по три записи данных: по скорости ветра, по направлению ветра и по высоте волны). чтобы получить самый последний из всех трех.)

Что у меня пока есть:

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 местоположений, 3 записи на местоположение на каждый запуск веб-службы, поэтому у нас есть 30 записей с одинаковыми значениями в weather_time.) Могу ли я как-то использовать это в порядке или группировать или что-то?

Ответы [ 2 ]

2 голосов
/ 24 февраля 2011

2-ой FROM (через SQL-Select) должен получить вас за лат / долготу, максимальное соответствующее время для каждой категории. Затем общий запрос связывает местоположения с этим псевдонимом (MaxTimes), а затем повторно присоединяется к данным о погоде на основе любого максимального времени, соответствующего соответствующему классификационному элементу, для которого проверяется. Если вы получите значения NULL, вы можете просто обернуть эти столбцы как NVL (what_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 - это ваш список основных расположений ... выполняя ЛЕВНОЕ СОЕДИНЕНИЕ, вы говорите SQL, независимо от того, есть ли у меня совпадение с отметкой времени справа, покажите мне все местоположения.

Далее, PreQuery для MaxTimes. Думайте об этом подзапросе, как о предварительном сборе максимального времени на широту / долготу, на соответствующий ТИП измерения, сообщаемый через MAX (случай, когда ...) как FinalColumnName. Таким образом, для каждой записи она будет подходить только для ОДНОЙ из этих регистрационных записей и, если найдена, получит максимальное время этого столбца.

Итак, теперь у вас есть список местоположений, и вы оставили присоединенный к подзапросу MaxTimes, присоединенному к их соответствующим значениям LAT / LONG. Теперь запрос MaxTimes выполняет три левосторонних соединения с данными измерений, соответственно, для каждого измерения, поэтому я связал их с тем, для чего они предназначались ... отсюда ByWindDir, ByWindSpd и ByWaveHeight. Левое объединение, как и другие, основано на широте / долготе, его правильном типе («Направление ветра», «Скорость ветра» или «Высота волны») соответственно, И оно имеет то же время сопоставления этой категории.

Хорошая вещь этого запроса заключается в том, что если у вас есть время для одного местоположения широты / долготы, которые выключены, даже на секунды (то есть: направление ветра равно 11:58:02, а скорость ветра равно 11:58:05 и высота волны = 11:58:54, она все равно будет учитывать максимальное время каждого уникального измерения.

Наконец, список полей ... для привязки всех к одной строке, я получаю очевидные детали ... Так как каждая таблица была объединена для представления своих "вещей", у меня есть имена столбцов, представляющие КОНТЕКСТ ... Надеюсь, что это поможет вам понять этот запрос ... Примите одну часть за раз и найдите, какие ссылки на что.

0 голосов
/ 24 февраля 2011

попробовать:

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**
...