2010-03-28 2 views
1

У меня есть таблица ставок следующим образом:SQL Query - группа более одного столбца, но отчетливый

SellID INT FOREIGN KEY REFERENCES SellItem(SellID), 
CusID INT FOREIGN KEY REFERENCES Customer(CusID), 
Amount FLOAT NOT NULL, 
BidTime DATETIME DEFAULT getdate() 

Сейчас на моем сайте мне нужно, чтобы показать пользователю текущие ставки; только самую высокую цену, но без повторения одного и того же пользователя.

SELECT CusID, 
     Max(Amount) 
    FROM Bid 
    WHERE SellID = 10 
GROUP BY CusID 
ORDER BY Max(Amount) DESC 

Это лучшее, что я достиг до сих пор. Это дает CusID каждого пользователя с максимальной ставкой и заказывается по возрастанию. Но мне нужно также получить BidTime для каждого результата. Когда я пытаюсь поставить BidTime в к запросу:

SELECT CusID, 
     Max(Amount), 
     BidTime 
    FROM Bid 
    WHERE SellID = 10 
GROUP BY CusID 
ORDER BY Max(Amount) DESC 

Я сказал, что «Колонка„Bid.BidTime“недопустим в списке выбора, поскольку он не содержится ни в статистической функции или GROUP BY ".

Таким образом, я попытался:

SELECT CusID, Max(Amount), BidTime 
    FROM Bid 
    WHERE SellID = 10 
GROUP BY CusID, BidTime 
ORDER BY Max(Amount) DESC 

Но это возвращает все строки. Никакого различия. Какие-либо предложения по решению этой проблемы?

ответ

1

Один из способов, предполагая, что еще один способ думать об этом, чтобы вернуть Последний ставок на каждом пользователе:

SELECT b.cusID, b2.LatestBidTime, b.Amount 
FROM Bid b 
    JOIN (
     SELECT cusID, MAX(BidTime) AS LatestBidTime 
     FROM Bid 
     WHERE SellID = 10 
     GROUP BY cusID) b2 ON b.cusID = b2.cusID AND b.BidTime = b2.LatestBidTime 
WHERE b.SellID = 10 
+0

Ошибка и таковая подразумевает, что OP хочет, чтобы время ожидания для максимального значения ставки, но я ищу для этого разъяснения. –

+0

Это работает :) Но мне нужно освежить мои знания о присоединениях ... Поскольку AdaTheDev был первым, кто отвечал, я предполагаю, что справедливо отметить его ответ как принятый. Однако OMG Ponies также дал замечательное объяснение :) –

0

Предположительно самая высокая ставка была сделана совсем недавно, не так ли? Так что просто положите MAX на BidTime.

SELECT CusID, Max(Amount), MAX(BidTime) 
FROM Bid 
WHERE SellID=10 
GROUP BY CusID ORDER BY Max(Amount) DESC 
+0

MAX (bidtime) не гарантируется, что оно связано с значением MAX (сумма). –

+0

Это был бы очевидный случай, но, к сожалению, я не проверяю, будет ли ставка, которая будет сделана, выше текущей максимальной ставки. –

+0

Большинство систем ставок не позволяют вводить новые ставки ниже предыдущих, поэтому это не всегда неверное предположение. – Gabe

1
select b.* 
from Bid b 
inner join (
    SELECT CusID, Max(Amount) as MaxBid 
    FROM Bid 
    WHERE SellID=10 
    GROUP BY CusID 
) bm on b.CusID = bm.CusID and b.Amount = bm.MaxBid 
where b.SellID = 10 
ORDER BY b.Amount DESC 
2

Использование:

SELECT b.cusid, 
     b.amount, 
     b.bidtime 
    FROM BID b 
    JOIN (SELECT t.cusid, 
       t.sellid, 
       MAX(t.amount) AS max_amount 
      FROM BID t 
      WHERE t.sellid = 10 
     GROUP BY t.cusid, t.sellid) x ON x.max_amount = b.amount 
            AND x.cusid = b.cusid 
            AND x.sellid = b.sellid 
ORDER BY b.amount DESC 

Использование агрегатов означает, что вы не можете получить информацию по этому заданному значению в том же запросе. Вы должны связать копию таблицы с агрегированными данными (объединения являются типичным выбором), чтобы получить соответствующую информацию.

+0

Это неверно и может привести к тому, что записи будут исключены, так как он получает самую высокую ставку за 'cusid' через ** all **' sellid's. Если тот же 'cusid' имеет ставку более чем на' sellid', и они предлагают больше на 'sellid <> 10',' group by' вернет это более высокое значение, которое не будет соответствовать чему-либо в 'b' из-за предложение ограничительного where, в результате чего эта строка отфильтровывается. – RedFilter

+0

@OrbMan: Исправлено, спасибо. –