Фильтрация запросов по неделям - PullRequest
2 голосов
/ 19 января 2020

Как выполнить запрос (SELECT) в Postgresql, чтобы результаты столбца с разными датами находились между воскресеньем и субботой текущей недели.

Пример поддельного запроса:

SELECT * FROM table WHERE datecolumn BETWEEN CURRENT WEEK

В другом запросе у меня есть номер недели в году. Как сделать SELECT для этих дат, применяя в предложении WHERE указанный номер недели c в указанном c году.

Пример поддельного запроса:

SELECT * FROM table WHERE datecolumn BETWEEN WEEK15 FROM year 2020

Ответы [ 3 ]

1 голос
/ 19 января 2020

Я бы порекомендовал следующую пару условий:

where 
    date_column >= current_date - extract(dow from current_date) * interval '1 day'
    and date_column < current_date - (extract(dow from current_date) - 8) * interval '1 day'

Postgres 'date_trunc(week, ...) начинается неделями в понедельник, поэтому нам нужно что-то более сложное, используя extract(dow from ...), который возвращает 0 по воскресеньям.

Преимущество этого подхода состоит в том, что он является SARGeable, поскольку ни одна функция не применяется к фильтруемому столбцу. Это означает, что он с удовольствием воспользуется индексом столбца даты.

1 голос
/ 19 января 2020

Возможно, вы можете использовать что-то вроде этого:

SELECT * 
  FROM table 
  WHERE 
    EXTRACT(week FROM datecolumn) = EXTRACT(week FROM NOW())
    AND
    EXTRACT(isoyear FROM datecolumn) = EXTRACT(isoyear FROM NOW())

week - это номер недели ISO-8601. По определению, недели ISO начинаются по понедельникам, а первая неделя года содержит 4 января этого года. Другими словами, первый четверг года - первая неделя этого года.

В системе нумерации недель ИСО даты начала января могут быть частью 52-й или 53-й недели предыдущего года, а даты конца декабря - частью первой недели в следующем году.

Например, 2005-01-01 является частью 53-й недели 2004 года, а 2006-01-01 является частью 52-й недели 2005 года, а 2012-12-31 - частью первая неделя 2013 года.

Рекомендуется использовать поле isoyear вместе с week для получения согласованных результатов.

Если вам нужна индивидуальная (не ISO) нумерация недель - вы будете нужно создать свой собственный расчет.

0 голосов
/ 19 января 2020

Я бы использовал date_trunc(), но так. Для текущей недели:

where datecolumn >= date_trunc('week', now()) and
      datecolumn < date_trunc('week', now()) + interval '1 week'

Для n-й недели года это сложнее. Я думаю, что это то, что вы хотите:

where datecolumn >= (date_trunc('week', now()) -
                     (extract(week from now()) - 1) * interval '1 week' +
                     <n> * interval '1 week'
                    ) and
      datecolumn < (date_trunc('week', now()) -
                     (extract(week from now()) - 1) * interval '1 week' +
                     (<n> + 1) * interval '1 week'
                    )

Оба они структурированы, поэтому вычисления НЕ выполняются по столбцам, поэтому они совместимы с использованием индексов.

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