Объединение предложений SQL SUM

У меня есть сценарий, который требует выполнения четырех довольно больших запросов MySQL к одному и тому же подмножеству данных. Есть ли способ объединить их в один запрос?

Вот как выглядит запрос:

Select sum(value) From 
    ( Select lat, lng, value From `pop_geo_199` Where (
         (lat Between 38.1768916977 And 39.6131083023) And (lng Between -77.9596650363 And -76.1143349637)) 
        ) As FirstCut 
Where (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 79.85)

Как вы, вероятно, можете сказать, это географический запрос точек широты и долготы. Сначала запрос создает простое квадратное подмножество общей таблицы (FirstCut), а затем запускает триггерные функции, чтобы получить круглую область.

Из того, что я могу сказать, медленная часть запроса FirstCutпотому что таблица, на которую она опирается, содержит около 2,8 миллионов строк. FirstCutТем не менее, в этом случае, только около 27922 строк, так что триггерная часть идет очень быстро по сравнению.

Проблема в том, что мне нужно запустить несколько из них. Все они могут использовать то же самое FirstCutтем не менее, поскольку они имеют разные радиусы с центром в одной и той же области. Я хотел бы иметь возможность выполнить это только с одним запросом вместо четырех.

Вот как выглядит второй запрос:

Select sum(value) From 
    ( Select lat, lng, value From `pop_geo_199` Where (
         (lat Between 38.1768916977 And 39.6131083023) And (lng Between -77.9596650363 And -76.1143349637)) 
        ) As FirstCut 
Where (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 48.57) 

Как вы можете видеть, он точно такой же, как и другой, за исключением того, что последнее предложение WHERE немного отличается - условие - это просто меньшие радиусы (48,57 вместо 79,85).

Как эффективно объединить эти два запроса в один?

Я пытался использовать предложения CASE - это лучший подход?

Select 

sum(case when (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 79.85) then value else 0 end),

sum(case when (acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 < 48.57) then value else 0 end)

From ( Select lat, lng, value From `pop_geo_199` Where ((lat Between 38.1768916977 And 39.6131083023) And (lng Between -77.9596650363 And -76.1143349637)) ) As FirstCut;

1 ответ

Решение

Вы можете использовать CASE заявление для этого. Вы также можете переместить расчет в подзапрос:

Select 
     sum(case 
           when rad < 79.85
           then value 
           else 0 end)  1stQuerySum,
     sum(case 
           when rad < 48.57 
           then value 
           else 0 end)  2ndQuerySum
From  ( 
    Select lat, lng, value, 
           acos(0.627895140732*sin(radians(lat)) + 0.778297945677*cos(radians(lat))*cos(radians(lng)-(-1.34454929586))) * 6371 rad
    From `pop_geo_199` 
    Where (
         (lat Between 38.1768916977 And 39.6131083023) And 
         (lng Between -77.9596650363 And -76.1143349637)
    ) 
) As FirstCut 
Другие вопросы по тегам