El problema que se te presenta egostar es que no puedes utilizar la clausula order by en uniones, el order lo puedes colocar al final de la union para indicar el orden del resultado final.
Lo mejor es utilizar un procedimiento almacenado, si alguien encuentra una forma mejor por favor nos dice.
Miremos el ejemplo:
Código SQL
[-]
CREATE TABLE FACTURAS (
ID_FACTURA INTEGER NOT NULL,
ID_CLIENTE INTEGER NOT NULL,
FECHA DATE NOT NULL,
VALOR_TOTAL NUMERIC(15,2) NOT NULL
);
ALTER TABLE FACTURAS ADD CONSTRAINT PK_FACTURAS PRIMARY KEY (ID_FACTURA);
CREATE INDEX IDX_FACTURAS_FECHA ON FACTURAS (FECHA);
INSERT INTO FACTURAS (ID_FACTURA, ID_CLIENTE, FECHA, VALOR_TOTAL) VALUES (1, 1, '2008-01-01', 50000);
INSERT INTO FACTURAS (ID_FACTURA, ID_CLIENTE, FECHA, VALOR_TOTAL) VALUES (2, 1, '2008-01-01', 100000);
INSERT INTO FACTURAS (ID_FACTURA, ID_CLIENTE, FECHA, VALOR_TOTAL) VALUES (3, 1, '2008-02-01', 20000);
INSERT INTO FACTURAS (ID_FACTURA, ID_CLIENTE, FECHA, VALOR_TOTAL) VALUES (4, 2, '2008-02-01', 40000);
INSERT INTO FACTURAS (ID_FACTURA, ID_CLIENTE, FECHA, VALOR_TOTAL) VALUES (5, 3, '2008-02-01', 80000);
INSERT INTO FACTURAS (ID_FACTURA, ID_CLIENTE, FECHA, VALOR_TOTAL) VALUES (6, 4, '2008-02-01', 90000);
INSERT INTO FACTURAS (ID_FACTURA, ID_CLIENTE, FECHA, VALOR_TOTAL) VALUES (7, 2, '2008-03-01', 120000);
Supongamos por ejemplo que queremos saber la primera y la ultima factura entre dos fechas, este procedimiento lo puede hacer:
Código SQL
[-]
SET TERM ^ ;
CREATE OR ALTER PROCEDURE SP_FACTURAS (
fecha_inicial date,
fecha_final date)
returns (
id_factura integer,
fecha date,
valor_total numeric(15,2))
as
begin
-- Procedimiento para saber la primera y la ultima factura
-- en un rango de fechas
-- Busca la primera factura
select first 1 id_factura,
fecha,
valor_total
from facturas
where fecha between :fecha_inicial and :fecha_final
order by id_factura
into :id_factura,
:fecha,
:valor_total;
if (id_factura is not null) then
suspend;
-- Busca la ultima factura
select first 1 id_factura,
fecha,
valor_total
from facturas
where fecha between :fecha_inicial and :fecha_final
order by id_factura desc
into :id_factura,
:fecha,
:valor_total;
if (id_factura is not null) then
suspend;
end^
SET TERM ; ^
GRANT SELECT ON FACTURAS TO PROCEDURE SP_FACTURAS;
GRANT EXECUTE ON PROCEDURE SP_FACTURAS TO SYSDBA;
El if (id_factura is not null) es para evitar que te salgan registros nulos cuando no hay facturas en el ranog de fechas.
Ejecuta el procedimiento con estos casos, correlos uno por uno
Código SQL
[-]
select * from SP_FACTURAS('01/01/2008', '01/01/2008');
select * from SP_FACTURAS('01/01/2008', '01/04/2008');
select * from SP_FACTURAS('01/04/2008', '01/04/2008');
Espero que les sea de utilidad.