Sql选择两个按一列分组的Max事件

时间:2015-04-21 23:04:26

标签: sql sql-server

我有下表:

+----------+------+
| country  | event     |
+----------+-----------+
|   usa    | running   |
|   usa    | running   |
|   usa    | running   |
|  canada  | running   |
|  Canada  | running   |
|   usa    |  javline  |
|  canada  |  javline  |
|  canada  |  javline  |
|  canada  |  javline  |
+----------+-----------+

我希望通过sql查询获得以下内容:

USA    |  Running |  3
Canada |  Javline |  3

我尝试在MS sql server上使用以下查询:

select country, case when c > 1 then null else event end event 
  from (select country, [ModelName], recs, count(*) over (partition by event, recs ) c, 
           row_number() over (partition by country order by recs desc) rn
  from (select country, event, count(*) recs
          from table
         group by country, event)  )
 where rn = 1
 order by 1

但是我收到了一个错误:

  

Msg 102,Level 15,State 1,Line 12
  ')'附近的语法不正确。

任何指向正确解决方案的指标都表示赞赏。感谢。

2 个答案:

答案 0 :(得分:1)

您需要在子查询中添加别名:

select 
    country, 
    case when c > 1 then null else event end event 
from (
    select  -- No event here
        country, 
        [ModelName], 
        recs, 
        count(*) over (partition by event, recs ) c, 
        row_number() over (partition by country order by recs desc) rn
    from (
        select country, event, count(*) recs -- No ModelName here
        from [table]
        group by country, event
    ) x -- You need to put an alias here
)t -- and here
 where rn = 1
 order by 1

请注意,上述查询仍会产生错误:

  

列名称无效' ModelName'。

     

无效的列名称' event'。

这是因为ModelName未包含在最里面的子查询中,event未包含在最外面的子查询中。


根据您的示例数据,您可以使用此查询来获得所需的结果:

;WITH Cte AS(
    SELECT Country, Event, COUNT(*) AS CC
    FROM [Table]
    GROUP BY Country, Event
)
,CteRowNumber AS(
    SELECT *,
        RN = ROW_NUMBER() OVER(PARTITION BY Country ORDER BY CC DESC)
    FROM Cte
)
SELECT Country, Event, CC
FROM CteRowNumber
WHERE RN = 1

答案 1 :(得分:1)

您可以使用cte中的窗口函数来执行此操作:

-- this counts a number per each country and event
with q as(
  select country,event,
  row_number() over(partition by country,event order by country) r
  from your_table t
  )
--this takes only the maximum of them
select * 
from q
where r=(select max(r) 
          from q q2 
          where q2.country=q.country)

结果:

    | country |   event | r |
    |---------|---------|---|
    |  canada | javline | 3 |
    |     usa | running | 3 |