Как объединить две таблицы на трех условиях? - PullRequest
2 голосов
/ 20 июля 2011

надеюсь, кто-то может понять, что я делаю здесь не так.Задача кажется довольно простой, но, очевидно, за мной.

У меня есть две таблицы, и я пытаюсь добавить данные об осадках.В двух таблицах должны быть согласованы три условия, чтобы получить правильные данные об осадках для каждого участка поля, например, год, широта и долгота.Я попытался с помощью следующих запросов (среди других неудачных запросов, которые я даже больше не помню):

SELECT f.*, g.* 
  FROM fieldSites f  LEFT OUTER JOIN gpcp_precipitation2 g
    ON f.date = g.year 
   AND f.d_lat = g.lat
 WHERE f.d_lon = g.lon; 

на этот тайм-аут

и:

SELECT *
FROM fieldSites
INNER JOIN gpcp_precipitation2 
  ON (fieldSites.d_lon = gpcp_precipitation2.lon 
  AND fieldSites.d_lat = gpcp_precipitation2.lat 
  AND fieldSites.date = gpcp_precipitation2.year);

и этот тайм-аут на меня.

Я бы хотел сделать дамп в файл .csv, но сейчас я просто хочу выполнить успешный запрос.

Вот мои таблицы:

left table: fieldSites

siteId  d_lat  d_lon   year  data1  data2  country      
  1     -13.75  18.75   2009  0.598  0.351  Angola       
  1     -13.75  18.75   2008  0.654  0.330  Angola       
  1     -13.75  18.75   2007  0.489  0.381  Angola       
  1     -13.75  18.75   2006  0.554  0.389  Angola       
  1     -13.75  18.75   2005  0.321  0.321  Angola       
  1     -13.75  18.75   2004  0.598  0.351  Angola       
  1     -13.75  18.75   2003  0.654  0.330  Angola       
  1     -13.75  18.75   2002  0.489  0.381  Angola       
  1     -13.75  18.75   2001  0.554  0.389  Angola       
  2     -78.75  163.75  2009  0.285  0.155  Antarctica   
  2     -78.75  163.75  2008  0.285  0.155  Antarctica   
  2     -78.75  163.75  2007  0.285  0.155  Antarctica   
  2     -78.75  163.75  2006  0.285  0.155  Antarctica   
  2     -78.75  163.75  2005  0.285  0.155  Antarctica   
...1052 sites, 11 years, 11496 rows

right table: gpcp_precipitation2

siteId   lat    lon   year  precipitation
1        81.5   1.25  2009  93.36571912   
1        81.5   1.25  2008  93.36571912   
1        81.5   1.25  2007  93.36571912   
1        81.5   1.25  2006  93.36571912   
1        81.5   1.25  2005  93.36571912   
1        81.5   1.25  2004  93.36571912   
1        81.5   1.25  2003  93.36571912   
1        81.5   1.25  2002  93.36571912   
1        81.5   1.25  2001  93.36571912   
1        81.5   1.25  2000  93.36571912   
1        81.5   3.75  2009  93.36571912 
1        81.5   3.75  2008  93.36571912   
1        81.5   3.75  2007  93.36571912

... 92300 rows  

Я хочу вот что:

siteId  d_lat  d_lon   year  data1  data2  country      precipitation  
  1     13.75  18.75   2009  0.598  0.351  Angola       144.286
  1     13.75  18.75   2008  0.654  0.330  Angola       114.970
  1     13.75  18.75   2007  0.489  0.381  Angola       70.000
  1     13.75  18.75   2006  0.554  0.389  Angola       174.179
  1     13.75  18.75   2005  0.321  0.321  Angola       174.743
  1     13.75  18.75   2004  0.598  0.351  Angola       70.506
  1     13.75  18.75   2003  0.654  0.330  Angola       173.716
  1     13.75  18.75   2002  0.489  0.381  Angola       74.162
  1     13.75  18.75   2001  0.554  0.389  Angola       139.445
  2     78.75  163.75  2009  0.285  0.155  Antarctica   0
  2     78.75  163.75  2008  0.285  0.155  Antarctica   0
  2     78.75  163.75  2007  0.285  0.155  Antarctica   0
  2     78.75  163.75  2006  0.285  0.155  Antarctica   0

Я делаю что-то совершенно глупое?Я в тупике.Большое спасибо за любой совет.

Ответы [ 3 ]

5 голосов
/ 20 июля 2011
Select fieldSites.*, precipitation.*
From fieldSites
Inner Join gpcp_precipitation2 As precipitation On precipitation.siteId = fieldSites.siteId
Where
    fieldSites.d_year = precipitation.year And
    fieldSites.d_lat = precipitation.lat And
    fieldSites.d_lon = precipitation.lon

Если для этого запроса истекло время ожидания, у вас есть проблема с индексацией, не обязательно проблема с запросом. Это дает вам несколько предикатов в предложении where для фильтрации, так что это должно немного уменьшить ваши объединения, но вам может понадобиться индекс, который включает siteId, year, lat и lon для обеих таблиц.

3 голосов
/ 20 июля 2011

Добавьте индекс (date, d_lat, d_lon) к первой таблице и индекс (year, lat, lon) ко второй таблице.Затем попробуйте присоединиться.

Из ваших комментариев я предлагаю вам использовать второй запрос:

SELECT *
FROM fieldSites
INNER JOIN gpcp_precipitation2 
  ON  fieldSites.d_lon = gpcp_precipitation2.lon 
  AND fieldSites.d_lat = gpcp_precipitation2.lat 
  AND fieldSites.date = gpcp_precipitation2.year ;

Можете ли вы также опубликовать план запроса для вышеупомянутого, теперь, когда вы добавили несколькоиндексы?(используйте EXPLAIN SELECT ...)

2 голосов
/ 20 июля 2011
SELECT *
FROM fieldSites
INNER JOIN gpcp_precipitation2 
  ON (fieldSites.d_lon = gpcp_precipitation2.lon 
  AND fieldSites.d_lat = gpcp_precipitation2.lat 
  AND fieldSites.date = gpcp_precipitation2.year);

Последняя строка:

AND fieldSites.date = gpcp_precipitation2.year);

Согласно вашим таблицам это должно быть fieldSites.year Это опечатка или ошибка?

...