SQL-запрос - группировка по нескольким столбцам, но различная - PullRequest
1 голос
/ 28 марта 2010

У меня есть таблица предложений, как показано ниже:

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

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

Ответы [ 4 ]

2 голосов
/ 28 марта 2010

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

  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

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

1 голос
/ 28 марта 2010
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 
1 голос
/ 28 марта 2010

Один из способов предположить, что существует другой способ, - вернуть ПОСЛЕДНЮЮ ставку для каждого пользователя:

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 голосов
/ 28 марта 2010

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

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