2009-07-13 16 views
4

最大値だけでなく最大値を持つ行数を返すT-SQLクエリを作成したいと思います。サブクエリなしの最大値のSQLサーバーの数

--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!) 

ようにシンプルな方法がありますがあり、私はサブクエリに参加INNERによって正しくこれを行うことができ、私は

--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!) 

が出ているものよりも優れた方法であることが、それは無駄なようだしなければなりませんクエリ#1として返されますが、クエリ#2のように正しい結果が返されますか?

MS SQL Server 2000の

EDIT:私はこれを入力することで私の最初の試行では、二つの重要なGROUPのBYS上記逃し、私は彼らに EDITを追加しました:ケイドルーが書いたバージョンは、私が書いたものであることをふり

+2

"無駄なようだ" - あなたがあなたの気持ちに手の込んだだろうか?私はこれに対して3つの異なる(より良い)ソリューションを書くことができますが、すべてサブクエリを伴い、無駄になりたくはありません。 –

+0

無駄(adj)=誰かが私に同じことをする1つのライナーを表示したときの気持ち – user130582

+0

SQL Server 2005/2008では、row_number(またはrank)関数を使用してサブクエリを避けることができます。 2000年にサブクエリを避ける方法はありません。 –

答えて

2

私は右だと思う:

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

これを行う最も簡単な方法は、LibraryBranchIdを取得し、曜日チェックアウトを選択することです。 コードを記述するたびにプログラムでカウントし、プログラムによってmax dayscheckedoutを取得します。

0

これはいかがですか?

select LibraryBranchId, MAX(daysCheckedOut), count(daysCheckedOut) 
from books B 
where daysCheckedOut = (select MAX(daysCheckedOut) from books where LibraryBranchID = B.LibraryBranchID) 
group by LibraryBranchId 
0

もう一つの "無駄" な方法は:

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 
関連する問題