Если более 10% результатов находятся над X в mysql

У меня есть таблица базы данных со списками показаний температуры из многих мест в ряде зданий. Мне нужен запрос, который даст мне true или false, если более 10% показаний в здании, взятых на дату, больше X

Я не ищу среднего. Если есть 100 измерений, сделанных в здании на дату, и 10 из них над X (скажем, 80 градусов), то создайте флаг.

Таблица положена вне как

 Building # location #    date     temperature
| 123      |  555      |2016-04-08 | 68.5     |
| 123      |  556      |2016-04-08 | 70.2     |
| 123      |  557      |2016-04-08 | 65.4     |
| 888      |  999      |2013-03 22 | 80.4     |

Типично здание имело бы над 100 чтениями. Есть много сотен записей даты / здания в таблице

Можно ли это сделать с помощью одного запроса mysql и можете ли вы поделиться этим запросом со мной?


Я, очевидно,не прояснил свой вопрос.

Результат, который я ищу, является единственным истинным или ложным.

Если более 10% результатов для комбинации здание/дата были более X (скажем, 80%), то показать true, или какой-то флаг, равный true.

Известные поля будут строиться и датироваться. Расположение не имеет значения и может быть проигнорировано. Таким образом, учитывая входные данные здания (123) и дата (2016-04-08) более 10% записей в таблице, которые имеют, что номер здания и дата больше, чем X (например, 80). Единственные данные, которые будут проверены, — это данные для этого здания и даты. Таким образом, запрос закончится в:

where building_id=`123` AND date =`2016-04-08`

Я не ищу среднее или медиану. Я не ищу, чтобы увидеть список данных для этого 10%. Я просто ищу истину или ложь.

2 ответа

  1. Можно использовать условную агрегацию, что-то вроде этого:

    select building, date,
           (case when avg(temperature > x) > 0.1 then 'Y' else 'N' end) as flag
    from t
    group by building, date;
    
  2. Чтобы вернуть здание и дату, и «создать флаг» для строк, где более 10% показаний для этого здания на эту дату превышают заданное значение X …

     SELECT r.building
          , DATE(r.date)
          , ( SUM(r.reading > X ) > SUM(.10) ) AS _flag
       FROM myreadings r
      GROUP BY r.building, DATE(r.date)
    

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


    ПОСЛЕДУЮЩИЙ

    На основе обновления вопроса… чтобы вернуть строку для одного здания и одной даты, добавьте предложение WHERE, как показано в вопросе. И удалить выражения из списка выбора.

     SELECT ( SUM(r.reading > X ) > SUM(.10) ) AS _flag
       FROM myreadings r
      WHERE r.building = '123'
        AND r.date    >= '2016-04-08'
        AND r.date    <  '2016-04-08' + INTERVAL 1 DAY 
    

    Если для данного здания и заданной даты нет строк, запрос возвращает ноль строк. Если имеется хотя бы одна строка, а число строк, имеющих значение больше X, превышает 10% от общего числа строк, запрос возвращает одну строку, при этом _flag имеет значение 1 (TRUE). В противном случае запрос вернет одну строку с _flag, имеющей значение 0 (FALSE).

    Если вы хотите, чтобы запрос возвращал строку, даже если в таблице нет совпадающих строк, это может быть выполнено с помощью более сложной инструкции SQL.

    Если вы хотите, чтобы запрос возвращал строковые значения 'TRUE'или'FALSE', это также может быть выполнено.

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