#sql #postgresql
Вопрос:
Я пытаюсь рассчитать или подсчитать количество строк, в которых разница в дате составляет определенную сумму, но не знаю, как это сделать
select count(case when date_diff('day', min_time, max_time) <= 7 then 1 else null end) / count(*)
from table
но, похоже, это не помогает, не уверен, что есть лучший способ реализовать это, спасибо!
Комментарии:
1. Вероятно, проблема в целочисленном делении. Умножьте числитель на 1,00 перед делением.
2. спасибо, я попробовал * 1.0, и он все еще ошибался, как вы думаете, мой код здесь правильный даже с * 1.0? @shawnt00
3. Вы не можете использовать Postgres, так как
date_diff()
в Postgres нет функции. Какую СУБД вы действительно используете?
Ответ №1:
Редактировать: как упоминал @shawnt00 в комментарии к вопросу, проблема, скорее всего, в том, что вы делите целые числа (в результате получается целое число, то есть 0 или 1 в данном случае). Добавление a * 1.0
должно решить проблему (или приведение к float8, если вы предпочитаете).
Вы можете использовать это FILTER
предложение для этого:
select count(*) filter (where date_diff('day', min_time, max_time) <= 7) * 1.0 / count(*)
from table
Хотя, поскольку похоже, что вы вычисляете среднее значение, возможно, что-то подобное было бы проще всего:
select avg(case when date_diff('day', min_time, max_time) <= 7 then 1.0 else 0.0 end)
from table
Комментарии:
1. спасибо, этот метод фильтрации работает также в postgres и mysql?
2. кроме того, просто в учебных целях, если бы я хотел использовать регистр вместо фильтра, мог бы это быть просто регистр( когда date_diff…?
3. Нет, насколько я знаю, mysql не имеет
FILTER
. Он является частью стандарта SQL 2003, но является необязательным. Смотрите это для получения дополнительной информации.4. @Chris90 комментарий shawnt00 к вашему вопросу должен на самом деле решить проблему
5. @Chris90: почти всегда есть способ переписать a
FILTER
с помощью aCASE WHEN
, и ваш первоначальный запрос должен сделать свое дело. Единственные случаи, когда вам действительно нужноFILTER
, — это когда для агрегатной функции нет нейтрального элемента. Например,ARRAY_AGG
не будет игнорироватьсяnull
, поэтому нет способа агрегировать только подмножество строк (кроме использованияFILTER
). Я виделFILTER
, что это было немного быстрее, чемCASE WHEN
, хотя у меня нет никакого примера/ссылки, чтобы показать это.
Ответ №2:
Почему бы не использовать count(*)
предложение with a where для выбора строк?
Комментарии:
1. bc это не единственное значение в инструкции select
2. Просто включите
count(*)
и другие поля в поле «Выбрать». Добавление agroup by
при необходимости