2010-08-28 21 views
7

tengo una tabla llamada order que contiene columnas id, user_id, price y item_id. Los precios de los artículos no son fijos y me gustaría seleccionar el pedido más caro de cada artículo. Quiero seleccionar user_id, item_id y price en la misma consulta. Intenté la siguiente consulta pero no devuelve el conjunto de resultados correcto.Seleccionar varios valores máximos

SELECT user_id, item_id, MAX(price) 
FROM order 
GROUP BY item_id 

Algunas de las filas devueltas por esta consulta tienen el user_id incorrecto. Sin embargo, todas las filas en el conjunto de resultados muestran el precio más alto correcto de cada artículo.

Respuesta

9

Es posible que desee utilizar una tabla derivada, de la siguiente manera: caso

SELECT o1.item_id, o1.max_price, o2.user_id user_of_max_price 
FROM  (
      SELECT item_id, MAX(price) max_price 
      FROM `order` 
      GROUP BY item_id 
     ) o1 
JOIN  `order` o2 ON (o2.price = o1.max_price AND o2.item_id = o1.item_id) 
GROUP BY o1.item_id; 

prueba:

CREATE TABLE `order` (user_id int, item_id int, price decimal(5,2)); 

INSERT INTO `order` VALUES (1, 1, 10); 
INSERT INTO `order` VALUES (1, 2, 15); 
INSERT INTO `order` VALUES (1, 3, 8); 
INSERT INTO `order` VALUES (2, 1, 20); 
INSERT INTO `order` VALUES (2, 2, 6); 
INSERT INTO `order` VALUES (2, 3, 15); 
INSERT INTO `order` VALUES (3, 1, 18); 
INSERT INTO `order` VALUES (3, 2, 13); 
INSERT INTO `order` VALUES (3, 3, 10); 

Resultado:

+---------+-----------+-------------------+ 
| item_id | max_price | user_of_max_price | 
+---------+-----------+-------------------+ 
|  1 |  20.00 |     2 | 
|  2 |  15.00 |     1 | 
|  3 |  15.00 |     2 | 
+---------+-----------+-------------------+ 
3 rows in set (0.00 sec) 
+0

Funcionó perfectamente. Gracias, Daniel! – Ohas

1

Su consulta agrupa las filas por item_id. Si tiene varios elementos con item_id 1, con diferente un user_id, solo seleccionará el primer user_id, no el user_id con el precio más alto.

+0

Sí, eso es correcto. Entonces, ¿cómo logro lo que estoy tratando de hacer aquí? Estoy tratando de averiguar quién compró el artículo al mejor precio y cuál fue ese precio. – Ohas

0

Deberá agrupar por item_id Y user_id (mostrando el precio máximo por artículo por usuario), o si solo desea el elemento en el grupo, deberá volver a pensar la columna user_id. p. muestre el precio máximo de un artículo y muestre al ÚLTIMO usuario que hizo un cambio en el precio, O muestre el precio Máx. de un artículo y muestre al usuario quién MADE el Precio Máx. por el artículo, etc. Mire this post para algunos patrones para hacer esto

+0

¿No puedo obtener el artículo, su precio máximo y el usuario que hizo ese precio en una consulta? – Ohas

2

Primero necesita obtener el precio máximo para cada identificación de artículo y luego volver a unirse al order para obtener los registros donde se solicitó el artículo por el precio máximo. Algo así como la siguiente consulta debería funcionar. Aunque devolverá todos los registros con los precios máximos de los artículos.

SELECT user_id, item_id, price 
FROM order o 
JOIN (
     SELECT item_id, max(price) max_price 
     FROM order 
     GROUP BY item_id 
    ) o2 
    ON o.item_id = o2.item_id AND o.price = o2.max_price; 
2

Esta es una per- pregunta de grupo máximo. Hay various approaches para este problema común. En MySQL es generalmente más rápido y más fácil de usar un nulo-autocombinación las subconsultas que cualquier cosa que implica:

SELECT o0.user_id, o0.item_id, o0.price 
FROM order AS o0 
LEFT JOIN order AS o1 ON o1.item_id=o0.item_id AND o1.price>o0.price 
WHERE o1.user_id IS NULL 

decir. "Seleccione cada fila donde no exista otra fila para el mismo artículo con un precio más alto".

(Si dos filas tienen el mismo precio máximo que conseguirá tanto regresado. ¿Qué es exactamente que hacer en el caso de un empate es un problema general de soluciones por grupo de máxima.)

+1

¿El benchmark en [el enlace que proporcionó] (http://kristiannielsen.livejournal.com/6745.html) muestra que el método de la tabla derivada (subconsulta no correlacionada) es mucho más rápido que el autocomprobar nulo? ... También solía pensar que null-self-join es ligeramente más rápido en MySQL, y de hecho estoy muy sorprendido con esos benchmarks. Tengo la sensación de que voy a hacer algunas pruebas yo mismo :) ... +1 de todos modos –

+1

Sí, los resultados variarán dependiendo del tamaño de las tablas y los índices implicados. Por lo general, encontré el null-auto-join más rápido sobre mi conjunto de datos particular en el pasado utilizando MySQL (cuyo soporte de subconsulta es relativamente reciente, por lo que quizás no esté tan optimizado como podría ser). Sería interesante investigar más con una versión reciente de MySQL. – bobince

1
SELECT user_id, item_id, MAX(price) 
FROM order 
GROUP BY item_id 

El SQL que usaste es contradictorio por GROUP. Una vez que use GROUP, MYSQL siempre seleccionará el PRIMERO user_id, pero el precio MÁS ALTO, esta es la razón por la cual el usuario está equivocado pero el precio es el correcto.

Puede intentar agregar ORDER BY price DESC para ver qué sucede, pero no lo intenté en mi entorno.

3

Tal vez esto es un poco más largo pero se gana en legibilidad

SELECT 
     * 
FROM 
    `order` 
JOIN 
    (
     SELECT 
      item_id, 
      MAX(price) price 
     FROM 
      `order` 
     GROUP BY 
      item_id 
    ) 
    USING(item_id, price); 
0

si quieres subir 2 de probar este fin ...

si desea que la parte superior 3 a continuación, sólo cambiar última condición donde item_rank in (1,2) ; a where item_rank in (1,2,3) ;

select * from 
    (select item_id , price 
    , @curRow % @curNval as item_rank 
    , @curRow := @curRow + 1 AS row_number 
    from `order` , (SELECT @curRow := 1 , @curNval := 3) r 
    order by item_id , price desc ) tab where item_rank in (1,2) ; 
+0

puede usar como item_rank> 2 o item_rank> n – Kapil

Cuestiones relacionadas