случай с различием дат

#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 с помощью a CASE WHEN , и ваш первоначальный запрос должен сделать свое дело. Единственные случаи, когда вам действительно нужно FILTER , — это когда для агрегатной функции нет нейтрального элемента. Например, ARRAY_AGG не будет игнорироваться null , поэтому нет способа агрегировать только подмножество строк (кроме использования FILTER ). Я видел FILTER , что это было немного быстрее, чем CASE WHEN , хотя у меня нет никакого примера/ссылки, чтобы показать это.

Ответ №2:

Почему бы не использовать count(*) предложение with a where для выбора строк?

Комментарии:

1. bc это не единственное значение в инструкции select

2. Просто включите count(*) и другие поля в поле «Выбрать». Добавление a group by при необходимости