如何从列

时间:2016-07-12 22:11:01

标签: sql sql-server-2012

我有这个问题:

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个最高成绩。

我已尝试仅group by rs.name而不是rs.name,r.rev_id,但这会导致错误。

提前致谢

3 个答案:

答案 0 :(得分:0)

所以你想要每个名字的最高值,限制为三行。这表明row_number()

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;

答案 1 :(得分:0)

如果你不介意写一个冗余的sql,你也可以这样做:

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是正确的,你可以发现它给你每likesname行,所以当你变化

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

它会给你正确的结果。

答案 2 :(得分:0)

您的查询的格式为 show rows with max(foo)。第一行攻击是Group By,但有时候,您需要有关聚合的更多信息。在这种情况下,通过 rev_id name 计算,您只需要那些 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变得更容易,并且可以节省您编写更复杂的查询。