¿Cuál es la forma más eficiente de generar este informe?

Dada una tabla (daily_sales) con decir 100k filas de los siguientes datos / columnas:

id rep sales date 1 a 123 12/15/2011 2 b 153 12/15/2011 3 a 11 12/14/2011 4 a 300 12/13/2011 5 a 120 12/12/2011 6 b 161 11/15/2011 7 a 3 11/14/2011 8 c 13 11/14/2011 9 c 44 11/13/2011 

¿Cuál sería la forma más eficiente de escribir un informe (completamente en SQL) mostrando las dos inputs más recientes (representante, ventas, date) para cada nombre, por lo que el resultado sería:

 a 123 12/15/2011 a 11 12/14/2011 b 153 12/15/2011 b 161 11/15/2011 c 13 11/14/2011 c 44 11/13/2011 

¡Gracias!

Para MySQL, explicado en el blog de @Quassnoi , un índice sobre (name, date) y el uso de esto:

 SELECT t.* FROM ( SELECT name, COALESCE( ( SELECT date FROM tableX ti WHERE ti.name = dto.name ORDER BY ti.name, ti.date DESC LIMIT 1 OFFSET 1 --- this is set to 2-1 ), CAST('1000-01-01' AS DATE)) AS mdate FROM ( SELECT DISTINCT name FROM tableX dt ) dto ) tg , tableX t WHERE t.name >= tg.name AND t.name <= tg.name AND t.date >= tg.mdate 

Para su información, su ejemplo está usando palabras reservadas en su mayoría y hace que sea horrible que tratemos de progtwigr en contra. Si tiene las columnas reales de la tabla, nos las da. Esto es postgres:

 select name,value, max(date) from the_table_name_you_neglect_to_give_us group by 1,2 

Eso te dará una list de nombre, valor, máximo (date) … aunque debo preguntar por qué darnos una columna llamada valor si no cambia en el ejemplo.

Digamos que tienes una columna de identificación … seremos consistentes con tu esquema y lo llamaremos 'ID' …

  select b.id from (select name,value, max(date) date from the_table_name_you_neglect_to_give_us group by 1,2) a inner join the_table_name_you_neglect_to_give_us b on a.name=b.name and a.value=b.value and a.date = b.date 

Esto le da una list de todas las identificaciones que son el máximo … ponerlo juntos:

 select name,value, max(date) from the_table_name_you_neglect_to_give_us group by 1,2 

unión todo

 select name,value, max(date) from the_table_name_you_neglect_to_give_us where id not in (select b.id from (select name,value, max(date) date from the_table_name_you_neglect_to_give_us group by 1,2) a inner join the_table_name_you_neglect_to_give_us b on a.name=b.name and a.value=b.value and a.date = b.date) 

Esperando que mi syntax sea correcta … debería estar cerca de todos modos. Puse un corchete alnetworkingedor de todo eso y luego selecciono * de (encima de la consulta) order por nombre … le da el order que desea.

Si entiendo lo que quieres decir … entonces esto PUEDE ser útil:

 SELECT main.name, main.value, main.date FROM tablename AS main LEFT OUTER JOIN tablename AS ctr ON main.name = ctr.rname AND main.date <= ctr.rdate GROUP BY main.name, main.date HAVING COUNT(*) <= 2 ORDER BY main.name ASC, main.date DESC 

Sé que SQL es más corto que las otras publicaciones, pero primero pruébalo …