Pregunta

Decir que tengo una mesa de 'órdenes' creados como:

CREATE TABLE orders (id SERIAL, 
                     customerID INTEGER,
                     timestamp BIGINT, 
                     PRIMARY KEY(id));

Fecha y hora siendo la marca de tiempo UNIX. Ahora quiero para seleccionar los identificadores de las órdenes más reciente para cada cliente. Como una vista estaría bien.

Sin embargo, la siguiente declaración

CREATE VIEW lastOrders AS SELECT  id,
                                  customerID, 
                                  MAX(timestamp) 
                                  FROM orders 
                                  GROUP BY customerID;

provoca un error de PostgreSQL:

  

ERROR: columna "orders.id" debe aparecer en el GROUP BY   cláusula o ser usado en una función de agregado

¿Qué estoy haciendo mal?

¿Fue útil?

Solución

Para este tipo de cosas que se pueden utilizar 2 enfoques. Uno ha sido ya demostrado por Jens.

Otro, es el uso de "DISTINCT ON" cláusula:

CREATE VIEW lastOrders AS
SELECT
DISTINCT ON (customerID)
    id,
    customerID,
    timestamp
FROM orders
ORDER BY customerID, timestamp desc;

Otros consejos

La siguiente consulta debería devolver sólo el último fin de que cada cliente.

CREATE  VIEW last_orders AS
SELECT  id, customer_id, timestamp
FROM    orders AS o
WHERE   timestamp = (
            SELECT  MAX(timestamp)
            FROM    orders AS oi
            WHERE   o.customer_id = oi.customer_id
        );

(Suponiendo que no se puede tener dos pedidos de un cliente con el mismo valor de marca de tiempo.)

Editar: DISTINCT ON de Postgres es una manera mucho niftier de hacer esto. Estoy contento de haber aprendido de él. Sin embargo, lo anterior funciona para otros RDBMS.

kquinns respuesta va a fijar la excepción, pero no es lo que busca.

No sé las características de MySQL, pero algo como esto iba a trabajar con Oracle:

select a.*
from 
    orders a, 
    (select customerID, max(timestamp) timestamp 
        from orders group by customerID
    ) b
where a.customer_id = b.customerID
and a.timestamp = b.timestamp

realidad con Oracle se podría utilizar las funciones analíticas, pero no creo que están disponibles en MySQL

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top