Если это действительно то, что вы хотите, так странно, как кажется, тогда как другой подход можно забыть настои и подзапрос к таблице, чтобы получить минимальные и использование аналитический подход вместо:
select orderdate
from (
select o.*,
row_number() over (order by to_char(orderdate, 'MMDD')) as rn
from orders o
)
where rn = 1;
ORDERDATE
---------
01-JAN-14
row_number()
эффективно добавляет псевдо-столбец каждой строки в исходной таблице, основываясь на месяц и день в дату заказа. Значения rn
уникальны, поэтому будет одна строка, помеченная как 1, которая будет с самого раннего дня в самый ранний месяц. Если у вас несколько заказов с одним и тем же днем / месяцем, скажем 01-янв-2013 и 01-янв-2014, то вы все равно получите ровно один с rn = 1
, но выбранный является неопределенным. Вам нужно будет добавить еще order by
условий, чтобы сделать его детерминированным, но я понятия не имею, что вы можете пожелать.
Это делается во внутреннем запросе; внешний запрос затем фильтрует, чтобы возвращались только записи, отмеченные rn = 1
; поэтому вы получите ровно одну строку от общего запроса.
Это также позволяет избежать ситуации, когда номер раннего дня не находится в самом раннем номере месяца - скажем, если вы только имели 01-янв-2014 и 02-фев-2014; сравнение дня и месяца отдельно будет искать 01-фев-2014, которого не существует.
SQL Fiddle (с добавлением анкера Томаса Черчиха, дающего тот же результат для этих данных).
Чтобы присоединиться результат против вашей таблицы счета, вам не нужно снова присоединиться к столу заказов - тем более не с крестом присоединиться, который перекос результаты. Вы можете сделать присоединиться (по крайней мере) два способа:
SELECT
o.orderno,
to_char(o.orderdate, 'DD-MM-YYYY'),
i.invno
FROM
(
SELECT o.*,
row_number() over (order by to_char(orderdate, 'MMDD')) as rn
FROM orders o
) o, invoices i
WHERE i.invno = o.invno
AND rn = 1;
Или:
SELECT
o.orderno,
to_char(o.orderdate, 'DD-MM-YYYY'),
i.invno
FROM
(
SELECT orderno, orderdate, invno
FROM
(
SELECT o.*,
row_number() over (order by to_char(orderdate, 'MMDD')) as rn
FROM orders o
)
WHERE rn = 1
) o, invoices i
WHERE i.invno = o.invno;
Первый выглядит, как он делает больше работы, но планы выполнения одинаковы.
SQL Fiddle с вашим запросом на получение макаронных изделий, который получает два ряда назад, и эти два, которые его получают.
ОПИСАНИЕ _WHERE может содержать несколько столбцов, которые действительны только для подзапроса, afaik – Sathya
Я не понимаю требования из вашего описания, можете ли вы опубликовать небольшой набор выборочных данных вместе с ожидаемым выходом? – ninesided
Конечно, извините за путаницу. Добавлено в OP. (Извините за форматирование ... не уверен, как с этим бороться) – Restricted