Если поле created_at
уже проиндексировано, я просто буду искать все строки со значением created_at
между X и Y. Таким образом можно использовать индекс.
Например, чтобы получить строки со значением created_at
на 3-й неделе 2015 года, вы должны запустить:
select *
from questions
where created_at between '2015-01-11' and '2015-01-17'
Это позволит использовать индекс.
Если вы хотите указать неделю в предложении where, вы можете использовать функции date_part
или extract
, чтобы добавить столбец в эту таблицу, в котором будут храниться год и неделя #, а затем проиндексировать этот столбец, чтобы запросы могли использовать его. .
Если вы не хотите добавлять столбец, вы, конечно, можете использовать любую функцию в предложении where и запросить таблицу, но вы не сможете воспользоваться преимуществами каких-либо индексов.
Поскольку вы упомянули, что не хотите добавлять столбец в таблицу, я бы рекомендовал добавить индекс на основе функций.
Например, если ваш ddl был:
create table questions
(
id int,
created_at timestamp,
title varchar(20)
);
insert into questions values
(1, '2014-12-31 09:43:42','"Add things"'),
(2, '2013-11-23 02:48:55','"How do I ruby?"'),
(3, '2015-01-15 15:11:19','"How do I python?"');
create or replace function to_week(ts timestamp)
returns text
as 'select concat(extract(year from ts),extract(week from ts))'
language sql
immutable
returns null on null input;
create index week_idx on questions (to_week(created_at));
Вы можете запустить:
select q.*, to_week(created_at) as week
from questions q
where to_week(created_at) = '20153';
И получить:
| ID | CREATED_AT | TITLE | WEEK |
|----|--------------------------------|--------------------|-------|
| 3 | January, 15 2015 15:11:19+0000 | "How do I python?" | 20153 |
(отражает третью неделю 2015 года, т.е. '20153'
)
Fiddle: http://sqlfiddle.com/#!15/c77cd/3/0
Аналогичным образом вы можете запустить:
select q.*,
concat(extract(year from created_at), extract(week from created_at)) as week
from questions q
where concat(extract(year from created_at), extract(week from created_at)) =
'20153';
Fiddle: http://sqlfiddle.com/#!15/18c1e/3/0
Но он не будет использовать индекс, основанный на функциях, потому что его нет. Кроме того, он не будет использовать какой-либо индекс, который может быть у вас в поле created_at
, потому что, хотя это поле может быть проиндексировано, вы на самом деле не ищете в этом поле. Вы ищете результат применения функции к этому полю. Таким образом, индекс самого столбца использовать нельзя.
Если таблица большая, вам понадобится либо индекс на основе функции, либо столбец, содержащий эту неделю, которая сама индексируется.
03.01.2015