PostgreSQL - Как игнорировать грубые ошибки при использовании AVG () и MAX ()? - PullRequest
0 голосов
/ 14 октября 2018

У меня есть данные в таблице, и я хотел бы сознательно игнорировать некоторые заведомо неверные данные и взять среднее из наиболее вероятных данных.

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

Я мог бы использовать это, чтобы получить среднюю высоту .....

SELECT AVG(height) FROM people;

Хорошо, если данные быливсе добавлено правильно, но если они (скажем) десять человек в базе данных с правильной высотой, и один человек, рост которого был записан как миллиард сантиметров, тогда AVG () не вернет разумное значение - классический примериз GIGO (мусор входит, мусор выходит)

Есть ли способ настроить вышеупомянутую функцию SQL, чтобы игнорировать удаленные точки данных?- данные, которые настолько отличаются от всех остальных, что должны быть неверными?

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

ОБНОВЛЕНИЕ ....... Мой пример с использованием высоты был выбран для простоты объяснения.Любое предлагаемое решение НЕ МОЖЕТ просто фильтровать между разумными значениями (то есть высотой выше 1,5 м и ниже 2 м), потому что для реальных данных, которые я использую, я не знаю, что такое разумные значения!Решение должно отклонять данные, которые в значительной степени отличаются от большинства других данных - так что, я думаю, именно здесь пригодятся знания статистики.

Обновление 2) Извините, получаю отказ от ответаЯ ранее принял (хотя это было полезно!).Стандартное отклонение дает значение для «распространения» данных, но не дает никакого представления о том, где находятся отдаленные данные (т.е. тупо высокие люди или тупо короткие люди), поэтому такой пункт вроде этого ...

WHERE height BETWEEN (SELECT a-2*sd FROM cte) AND (SELECT a+2*sd FROM cte);

Не только удаляет одного тупо высокого человека с одного конца диапазона, но также удаляет всех людей «нормальной высоты» с другого конца диапазона!Я могу настроить выражение WHERE следующим образом ...

WHERE height BETWEEN (SELECT a-(sd/100) FROM cte) AND (SELECT a+(sd/100) FROM cte);

Но я ищу решение, которое не требует индивидуальной настройки для каждого отдельного набора данных

1 Ответ

0 голосов
/ 14 октября 2018

Вы можете использовать FILTER:

SELECT AVG(height) FILTER (WHERE height BETWEEN x AND y) AS avg_height
FROM people;

-- or `WHERE`:
SELECT AVG(height) AS avg_height
FROM people
WHERE height BETWEEN x AND y;

x и y - допустимые значения.


В качестве альтернативы вы можете отфильтровать значения, выходящие за пределы диапазона average() +/- 2*stddev()

WITH cte AS (
  SELECT AVG(height) a, STDDEV(height) sd
  FROM people
)
SELECT AVG(height)
FROM people
WHERE height BETWEEN (SELECT a-2*sd FROM cte) AND (SELECT a+2*sd FROM cte);

дБ <> демонстрация Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...