2010-06-18 11 views
7

Tengo tres tablas; Subastas, ofertas de subasta y usuarios. La estructura de la tabla es como la siguiente:Obteniendo los mejores resultados en un JOIN

Auctions: 

id title 
-- ----- 
    1  Auction 1 
    2  Auction 2 

Auction Bids: 

id user_id auction_id bid_amt 
-- ------- ---------- ------- 
    1  1   1   200.00 
    2  2   1   202.00 
    3  1   2   100.00 

Users es sólo una tabla estándar, con id y nombre de usuario.

Mi objetivo es unirme a estas tablas para que pueda obtener los valores más altos de estas ofertas, así como obtener los nombres de usuario relacionados con esas ofertas; así que tengo un conjunto de resultados, así:

auction_id auction_title auctionbid_amt user_username 
---------- ------------- -------------- ------------- 
     1 Auction 1   202.00   Bidder2 
     2 Auction 2   100.00   Bidder1 

Hasta ahora, mi consulta es la siguiente:

SELECT a.id, a.title, ab.bid_amt, u.display_name FROM auction a 
    LEFT JOIN auctionbid ab ON a.id = ab.auction_id 
     LEFT JOIN users u ON u.id = ab.user_id 
GROUP BY a.id 

Esto pone las filas individuales que busco, pero parece mostrar la bid_amt más bajo, no el más alto.

Respuesta

8

Puede usar la función MAX y una subselección para obtener la oferta máxima para cada subasta. Si se une a esta subselección con sus otras tablas y establece la cláusula where de la siguiente manera, debe obtener lo que está buscando.

SELECT a.id, a.title, ab.bid_points, u.display_name 
FROM Auction AS a 
INNER JOIN (SELECT auction_id, MAX(bid_points) AS maxAmount FROM auction_bids GROUP BY auction_id) AS maxBids ON maxBids.auction_id = a.id 
INNER JOIN auction_bids AS ab ON a.id = ab.auction_id 
INNER JOIN users AS u ON u.id = ab.user_id 
WHERE ab.auction_id = maxBids.auction_id AND ab.bid_amount = maxBids.maxAmount 

Espero que ayude.

+0

Esto es exactamente lo que necesitaba. ¡Gracias! – Keithamus

0

Prueba esto:

SELECT a.id, a.title, ab.bid_points, u.display_name FROM auction a 
    LEFT JOIN auctionbid ab ON a.id = ab.auction_id 
     LEFT JOIN users u ON u.id = ab.user_id 
GROUP BY a.id 
ORDER BY ab.bid_points DESC 

Si eso no funciona, pruebe a utilizar una subselección en auctionbids contienen algo así como

SELECT id, user_id, auction_id, MAX(bid_amt) FROM action_bids GROUP BY auction_id 
0

Trate de añadir la siguiente cláusula; no estoy seguro sobre el rendimiento

WHERE NOT EXISTS 
    (SELECT * FROM auctionbid abhigher 
    WHERE abhigher.auction_id = ab.auction_id 
    AND abhigher.auctionbid_amt > ab.auctionbid_amt) 

Excluye las ofertas de subasta de la consulta que tienen una oferta más alta para la misma subasta.

El único problema es que si tiene 2 ofertas iguales y ambas aparecerán. Una forma de deshacerse de ellos - pero es una opción relativamente arbitraria del ganador, es utilizar el ID de la subasta:

WHERE NOT EXISTS 
    (SELECT * FROM auctionbid abhigher 
    WHERE abhigher.auction_id = ab.auction_id 
    AND abhigher.auctionbid_amt >= ab.auctionbid_amt 
    AND abhigher.id > ab.id) 
1

Este es un típico problema global dentro del grupo. Se puede resolver utilizando el denominado exclusión auto izquierda unirse a

Pruebe lo siguiente:

SELECT a.id, a.title, ab.bid_points, u.displayname 
    FROM auction a 
    INNER JOIN auction_bids ab ON ab.auction_id = a.id 
    LEFT JOIN auction_bids b1 ON ab.auction_id = b1.auction_id 
    AND ab.bid_points < b1.bid_points 
    LEFT JOIN users u ON u.id = ab.user_id 
    WHERE b1.auction_id IS NULL 

Básicamente construye una unión entre el lado izquierdo y derecho, hasta que no encuentra una para el el lado izquierdo nunca más, y ese es el elemento más alto entonces.

Otra solución sería usar varias consultas (por supuesto) o una tabla agregada temporal.

+0

No es necesario una combinación izquierda en la tabla de usuarios. Se combina con la tabla 'auction_bids ab', y siempre habrá un usuario allí. Pregunta: ¿es posible que más de un usuario ofrezca la misma cantidad para una subasta?La consulta muestra todos ellos con la oferta más alta. Además, soy curioso si esto funciona lo suficientemente rápido cuando las tablas crecen más de unos pocos miles de filas. – ceteras

0

Aquí es lo que puede try..like edad school..nothing new..no necesita ir para unirse a izquierda ni nada else..rest depende de su requisito exacto

select A.id,A.title,max(AB.bid_amt),name 
from Auction A,AuctionBids AB,Users U 
where U.ID=AB.USER_ID AND A.ID=AB.ID 
group by A.ID,A.title,name 
Cuestiones relacionadas