Заказ по макс или мин с другого стола - PullRequest
2 голосов
/ 06 мая 2010

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

create table schedule (
   id varchar(40) primary key,
   attr1 int,
   attr2 varchar(20)
);

create table schedule_times (
   id varchar(40) foreign key schedule(id),
   fire_date date
);

Я хочу запросить таблицу расписания, получая атрибуты, а также следующие и предыдущие значения fire_dates в Java, иногда упорядочивая их по одному из атрибутов, но иногда упорядочивая их по предыдущим fire_date или следующим fire_date Упорядочить по атрибутам легко, я просто вставляю «упорядочить по» в строку, пока строю свое подготовленное утверждение. Я даже не уверен, как выбрать последнюю дату fire_date и следующую в одном запросе - я знаю, что могу найти следующую дату fire_date для данного идентификатора, выполнив

SELECT   min(fire_date)
FROM     schedule_times
WHERE    id = ? AND
         fire_date > sysdate;

и аналогичная вещь для предыдущей даты fire_date с использованием max() и fire_date < sysdate. Я просто рисую пробел о том, как включить это в один выбор из расписания, чтобы я мог получить как следующую, так и предыдущую дату fire_date за один снимок, а также как упорядочить по любому из этих атрибутов.

Ответы [ 3 ]

4 голосов
/ 06 мая 2010

Вы можете сделать это, используя два подзапроса в Left Join s.
Преимущество в том, что вы возвращаете NULL для ваших fire_dates, если нет следующего / предыдущего расписания.

Select id, attr1, attr2, next_fire_date, previous_fire_date
From schedule s
Left Join ( Select id, Min(fire_date) As next_fire_date
            From schedule_times st
            Where st.fire_date > Sysdate
            Group By id ) n
    On ( n.id = s.id )
Left Join ( Select id, Max(fire_date) As previous_fire_date
            From schedule_times st
            Where st.fire_date < Sysdate
            Group By id ) p
    On ( p.id = s.id )

Затем вы можете добавить ORDER BY на next_fire_date или previous_fire_date.


Если производительность имеет значение, создайте составной индекс на schedule_times( id, fire_date ), это позволит подзапросам читать только из этого индекса.

3 голосов
/ 06 мая 2010

Попробуйте что-то вроде этого:

select schedule.*,
(
    select max(si.fire_date) from schedule_times si where si.id = schedule.id and si.fire_date < sysdate
) as prevfire,

(
    select min(si.fire_date) from schedule_times si where si.id = schedule.id and si.fire_date > sysdate
) as nextfire
from schedule
where id = ?
order by attr1
0 голосов
/ 24 мая 2010

Изменить запрос на

SELECT Отличительный S.ID, ATTR1, ATTR2, LEAD (FIRE_DATE, 1, SYSDATE ) OVER (PARTITION по S.ID ORDER по S.ID) NEXT_FIRE_DATE, LAG (FIRE_DATE, 1, SYADATE ) OVER (PARTITION по S.ID, ORDER по S.ID) PREV_FIRE_DATE ИЗ SCHEDULE S, SCHEDULE_TIMES ST, ГДЕ ST.ID = S.ID;

ЭТО БЫЛ ПРОСТО ЗАПРОС. ВЫ МОЖЕТЕ ПОПРОБОВАТЬ ЭТО.

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

LEAD (sql_expr, смещение, по умолчанию) OVER (analytic_clause)

  1. sql_expr - это выражение для вычисления из начального ряда.
  2. смещение - индекс ведущей строки относительно текущего строка. смещение является положительным целым числом по умолчанию 1.
  3. по умолчанию - это значение, которое возвращается, если смещение указывает на строку вне диапазона раздела.

Синтаксис LAG аналогичен за исключением того, что смещение для LAG входит в предыдущие строки.

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