Почему в этом SQL-запросе в скобках указано другое значение? - PullRequest
1 голос
/ 19 марта 2019

Цель:

Найти процент аэропортов с высокими отметками (превышение> = 2000) по состояние из таблицы аэропортов.

В запросе псевдоним столбца процента как percentage_high_elevation_airports.

Может кто-нибудь объяснить, почему следующие 2 оператора SQL дают разные результаты:

Правильный результат:

SELECT state,
100.0 * sum(CASE WHEN elevation >= 2000 THEN 1 ELSE 0 END) / count(*)  as percentage_high_elevation_airports 
FROM airports 
GROUP BY state;

пример результата:

MS  0.0
MT  100.0
NC  11.1111111111111
ND  10.0

и неверный результат:

select 
state,
100.0 * (sum(case when elevation >= 2000 then 1 else 0 end)/count(*)) as percentage_high_elevation_airports
from airports
group by 1;

Результат выборки:

MS  0.0
MT  100.0
NC  0.0
ND  0.0

Единственная разница заключается в дополнительном размещении () вокруг суммы.

Ответы [ 3 ]

4 голосов
/ 19 марта 2019

Я бы написал так:

SELECT state,
       AVG(CASE WHEN elevation >= 2000 THEN 100.0 ELSE 0 END) as percentage_high_elevation_airports 
FROM airports 
GROUP BY state;

Проблема в том, что целое число арифметика.Некоторые базы данных делают целочисленное деление и возвращают целое число.Таким образом, 1/2 - это 0, а не 0.5.Некоторые базы данных также применяют это к avg() (но даже к некоторым, которые делают целочисленное деление на числовые средние).

Следует отметить, что это относится к базе данных.

1 голос
/ 19 марта 2019

Ваш вопрос не о другом / лучшем решении вашего запросано о неправильных результатах, которые вы получите, используя скобки, верно?Потому что:

sum(case when elevation >= 2000 then 1 else 0 end)

приводит к целому числу, а count(*) по определению является целым числом.Разделение между ними является целочисленным разделением, усекающим любые десятичные цифры.Таким образом, вы получаете 0 вместо 0.5 или 0.05.Чтобы избежать подобных ситуаций, вы можете умножить на действительное число, как вы: 100.0 сначала, а затем разделить.Или вы можете сделать это:

sum(case when elevation >= 2000 then 1.0 else 0.0 end)

, что приведет к сумме, которая является числом с плавающей запятой.В любом случае убедитесь, что хотя бы один из операндов деления является действительным числом .

0 голосов
/ 19 марта 2019

Попробуйте ниже - вам нужно изменить расположение скобок

select 
state,
(100.0 * sum(case when elevation >= 2000 then 1 else 0 end))/count(*)) as percentage_high_elevation_airports
from airports
group by 1
...