SQL Server количество макс значений без подзапроса - PullRequest
4 голосов
/ 13 июля 2009

Я хочу написать запрос T-SQL, который возвращает не только максимальное значение, но и количество строк, имеющих максимальное значение. Должен быть лучший способ, чем я придумал

 --wrong way 
 select LibraryBranchId, max(daysCheckedOut), count(daysCheckedOut) 
 from books group by LibraryBranchId

 LibraryBranchId   Expr1      Expr2
 ----------------------------------
 1                 100       398503  (WRONG!)
 2                 75         94303  (WRONG!)
 3                 120       103950  (WRONG!)

Я могу сделать это правильно, подключившись к подзапросу INNER, но это кажется расточительным

 --right way, but seems WAY too long
 select LibraryBranchId,max(daysCheckedOut),count(daysCheckedOut)
 from books inner join 
   ( select LibraryBranchId, max(daysCheckedOut) as maxDaysCheckedOut
     from books group by LibraryBranchId ) as maxbooks 
 on books.LibraryBranchId=maxbooks.LibraryBranchId
 where daysCheckedOut=maxDaysCheckedOut
 group by LibraryBranchId 

 LibraryBranchId   Expr1      Expr2
 ----------------------------------
 1                 100           17  (RIGHT!)
 2                 75            11  (RIGHT!)
 3                 120            2  (RIGHT!)

Так есть ли такой простой способ, как запрос № 1, но который возвращает правильный результат, как в запросе № 2?

MS SQL Server 2000

РЕДАКТИРОВАТЬ: я пропустил два важных GROUP BY выше с моей первой попытки войти в это, я добавил их РЕДАКТИРОВАТЬ: Притворись, что версия, которую написал Cade Roux, это то, что я написал

Ответы [ 4 ]

2 голосов
/ 13 июля 2009

Я думаю, что правильно:

SELECT maxbooks.LibraryBranchId, maxbooks.maxDaysCheckedOut, count(*)
FROM books
INNER JOIN (
    SELECT LibraryBranchId, max(daysCheckedOut) AS maxDaysCheckedOut
    FROM books
    GROUP BY LibraryBranchId
) AS maxbooks
    ON books.LibraryBranchId = maxbooks.LibraryBranchId
    AND books.daysCheckedOut = maxbooks.maxDaysCheckedOut
GROUP BY maxbooks.LibraryBranchId, maxbooks.maxDaysCheckedOut

Я не думаю, что есть более простой путь - концептуально, это пересечение двух множеств. Набор кортежей о ветвях и набор кортежей, удовлетворяющих этому.

0 голосов
/ 13 июля 2009

Еще один «расточительный» способ:

select LibraryBranchId, avg(daysCheckedOut) as maxDaysCheckedOut, count(*)
from
(
    select LibraryBranchId, daysCheckedOut
    from books b1
    where not exists 
    (
        select *
        from books b2
        where b2.LibraryBranchId = b1.LibraryBranchId
        and b2.daysCheckedOut > b1.daysCheckedOut
     )
) t
group by LibraryBranchId
0 голосов
/ 13 июля 2009

Как насчет этого?

select LibraryBranchId, MAX(daysCheckedOut), count(daysCheckedOut)
from books B
where daysCheckedOut = (select MAX(daysCheckedOut) from books where LibraryBranchID = B.LibraryBranchID)
group by LibraryBranchId 
0 голосов
/ 13 июля 2009

Самый простой способ сделать это - получить свой LibraryBranchId и выбрать свой распечатанный день затем подсчитывайте их программно везде, где вы пишете код, и программно получайте максимальное количество проверенных дней.

...