2016-07-12 10 views
0

列の各値から一つだけを取得する方法:私はこのクエリ持っ

SELECT 
    r.rev_id, rs.name, COUNT(ws.user_id) as likes 
FROM 
    Reviews AS r 
LEFT JOIN 
    Wasliked AS ws ON r.rev_id = ws.rev_id 
LEFT JOIN 
    Restaurants AS rs ON rs.rid = r.rest_id 
GROUP BY 
    rs.name, r.rev_id 
ORDER BY 
    likes DESC 

をし、結果は次のとおりです。

rev_id name likes 
------------------------ 
    7  rest1  5 
    10  rest1  3 
    6  rest1  2 
    2  rest3  2 
    1  rest2  2 
    5  rest3  1 
    8  rest4  1 

しかし、私はこのようになり、結果が欲しい:

rev_id name likes 
-------------------------- 
    7  rest1  5 
    2  rest3  2 
    1  rest2  2 

異なる名前で3つの最高の結果を得ています。

私は既にrs.name,r.rev_idの代わりにgroup by rs.nameにしようとしましたが、エラーが発生します。

ありがとうございます

答えて

0

だから、各名前の先頭の値は3行に制限します。これはrow_number()を提案する:あなたは冗長なSQLを書く気にしない場合

SELECT TOP 3 rev_id, name, likes 
FROM (SELECT r.rev_id, rs.name, COUNT(ws.user_id) as likes, 
      ROW_NUMBER() OVER (PARTITION BY rs.name ORDER BY COUNT(ws.user_id)) as seqnum 
     FROM Reviews r left join 
      Wasliked ws 
      on r.rev_id = ws.rev_id left join 
      Restaurants rs 
      on rs.rid = r.rest_id 
     GROUP BY rs.name, r.rev_id 
    ) x 
WHERE seqnum = 1 
ORDER BY likes desc; 
+0

同じ名前で間違った結果が表示されても動作しません – orestiskim

0

をまた、あなたはこのようにそれを行うことができます。

select top 3 t1.* 
from ( 
    select r.rev_id, rs.name, count(ws.user_id) as likes 
    from reviews as r 
    left join wasliked as ws on r.rev_id=ws.rev_id 
    left join restaurants as rs on rs.rid=r.rest_id 
    group by rs.name,r.rev_id 
) t1 
inner join (
    select name, max(likes) as likes 
    from (
     select r.rev_id, rs.name, count(ws.user_id) as likes 
     from reviews as r 
     left join wasliked as ws on r.rev_id=ws.rev_id 
     left join restaurants as rs on rs.rid=r.rest_id 
     group by rs.name,r.rev_id) tmp 
    group by name 
) t2 on t1.name = t2.name and t1.likes = t2.likes 
order by t1.likes desc 

@Gordon Linoffの答えはこれを行うには良い方法である、彼のSQLがありますちょうど、そしてあなたはそれがnameごとにあなたに最低likes行を与える見つけることができるので、あなたは

0に

ROW_NUMBER() OVER (PARTITION BY rs.name ORDER BY COUNT(ws.user_id)) as seqnum 

を変更したとき

ROW_NUMBER() OVER (PARTITION BY rs.name ORDER BY COUNT(ws.user_id) DESC) as seqnum 

正しい結果が得られます。

0

あなたのお問い合わせ先はの形式のものとなっており、max(foo)と表示されます。攻撃の最初の行はGroup Byですが、場合によっては集約に関する詳細情報が必要です。この場合は、計算によってをrev_idは、あなたがMAX(好きな)名前ごとにを持つ行のみを望んで好きました。それは存在テストを求めている:

with T (rev_id, name, likes) as (
    SELECT r.rev_id, rs.name, COUNT(ws.user_id) as likes 
    FROM Reviews as r 
    left join Wasliked as ws on r.rev_id=ws.rev_id 
    left join Restaurants as rs on rs.rid=r.rest_id 
    GROUP BY rs.name,r.rev_id 
) 
select * from T as L 
where exists (
     select 1 from T 
     where name = L.name 
     group by name 
     having max(likes) = L.likes 
) 
order by likes desc 

これは正しいことだ。

これまで提供されていたものよりも私のバージョンが好きです。非標準のtop N公式は使用されておらず、クエリは必要な論理演算、つまり定量化の観点からキャストされます。

実際には、where existsが簡単になり、さらに複雑なクエリを書く手間を省くことができます。

関連する問題