2016-04-19 10 views
0

「テーブル」のカウントで、「時間」で上位3の「ユーザーID」を検索する必要があります。入力と出力の例:グループごとに最大のカウントを持つ上位3つのIDを見つける - トリプルネストされたクエリを避けることは可能ですか?

ID UserID Time 
1  A  '1' 
2  A  '1' 
3  B  '2' 
4  B  '4' 
5  B  '4' 
etc 

望ましい結果:

Time UserID Number Rank 
'1'  A   17  1 
'1'  C   11  2 
'1'  Q   9  3 
'2'  B   13  1 
'2'  C   9  2 
'2'  M   7  3 
etc 

私は三重のクエリを使用してこれを実現することができましたが、簡素化する方法はありますか?そうでない場合は非常に遅くなり、このように思えるので、「を有する」節のようなものが、ここに適用できるかどう

select userID, Number, time, Rank from (

select userID, Number, time, 
Rank() over (partition by time order by Number DESC) as Rank 

from 

(select count(distinct(ID)) as Number, 
userID, 
time from table 
group by 2, 3) 

) 

where Rank <= 3 

は、私は思ったんだけど。

+2

あなたが提供するサンプルデータと希望の結果がお互いに一致する場合は、通常、必要なものを理解するのに役立ちます。さらに、クエリが正しい結果を生成する場合は、何が問題なのでしょうか?それは遅すぎますか?次に、既存のクエリのテーブル構造、インデックス、データカーディナリティ、および生成された実行計画に関する詳細情報を提供します。 –

+0

@VladimirBaranovより直接的なアプローチが利用可能な場合、クエリ自体をよりエレガントにすることを望んでいます。 –

+1

関連していないが: 'distinct'は***ではない***関数である。そして実際のクエリを投稿してください。あなたの質問のクエリは無効な構文です - 選択リストの 'rank(....) '部分が正しくなく、メインクエリに' from'がありません –

答えて

-1

私はその必要な場合は、後から追加することができます..それを使用してのポイントを取得していないため、このクエリが、そのランクの列が欠落してみてください:

select Time,UserID,count(1) as Number from table group by UserID,Time order by 1,3 desc 

PS:あなたがしたい場合ランクの列を追加して、選択してグループ化するだけでそれを追加しようとします。

0

これに満足していますか?

;with cte_ranking 
as 
(
select time, userid, count(time) as Number, rank() over (partition by time order by count(time) desc) as Rank 
from 
table 
group by time,userid 
) 
select * from cte_ranking 
where Rank < 3 
order by time 
+0

Postgres(一般的にはSQL)は、文の末尾に文の終わりの文字( ';')を必要とします。 –

+0

しかし、CTEは特に最初に終端文字を必要とします。この前に声明を出すには、それを終了させるべきです。それが必須です。これ自体が最初の文である場合は必須ではありません。 –

+0

CTEはありません*** *** *** *が必要です。 Microsoftでは伝統的に文を正しく終了する必要がないため、一部のMicrosoftツールでは必須となる場合があります。しかし、これはPostgresにとって必須ではありません。 Microsoftの場合でも、ステートメントではなくセミコロンでステートメントを終了する必要があります。しかし、この質問は特にPostgresに関するものであり、SQL Serverではなく、全く話題にはなっていません。 –

関連する問題