二级 Top N SQL 服务器

Second level Top N SQL server

我有一个 table,其中包含姓名、国家和身份。我想通过按名称和状态分组来获得总数,但只获得前 3 个国家/地区。

我的table:

+------+---------+--------+
| Name | Country | Status |
+------+---------+--------+
| ABC  | US      | Open   |
| ABC  | US      | Closed |
| ABC  | US      | Open   |
| ABC  | Japan   | Open   |
| ABC  | Japan   | Closed |
| ABC  | China   | Open   |
| ABC  | China   | Closed |
| ABC  | Italy   | Open   |
| DEF  | US      | Open   |
| DEF  | US      | Closed |
| DEF  | Japan   | Open   |
| DEF  | Japan   | Closed |
| DEF  | China   | Open   |
| DEF  | China   | Closed |
| DEF  | China   | Closed |
| DEF  | Italy   | Open   |
+------+---------+--------+

期望的输出:

+------+---------+--------+-------+
| Name | Country | Status | Total |
+------+---------+--------+-------+
| ABC  | US      | Open   |     2 |
| ABC  | US      | Closed |     1 |
| ABC  | Japan   | Open   |     1 |
| ABC  | Japan   | Closed |     1 |
| ABC  | China   | Open   |     1 |
| ABC  | China   | Closed |     1 |
| DEF  | US      | Open   |     1 |
| DEF  | US      | Closed |     1 |
| DEF  | Japan   | Open   |     1 |
| DEF  | Japan   | Closed |     1 |
| DEF  | China   | Open   |     1 |
| DEF  | China   | Closed |     2 |
+------+---------+--------+-------+

我尝试了以下查询,但没有得到我想要的结果。

Select rs.Name, rs.Country, rs.Status, Count(*) as total from (
SELECT Name, Country, Status, Rank() 
          over (Partition BY Name
                ORDER BY Country DESC ) AS Rank
        FROM table1 ) rs WHERE Rank <= 3

试试这个..

Select rs.Name, rs.Country, rs.Status, Count(*) as total from rs(
SELECT Name, Country, Status, Count(status) from mytable
    group by status order by Count(status) desc
 ) rs limit 3

您最初的查询绝对是正确的方向(我什至用它来确定您想要的输出)。但是,您想要的输出是多个聚合的结果,而不仅仅是单个分析函数。在下面的查询中,我首先聚合以获得总计,然后使用排名保留前 3 组。如果出现平局,此查询会选择按字母顺序排在第一位的国家/地区。

SELECT t.Name,
       t.Country,
       t.Status,
       t.Total
       DENSE_RANK() OVER (PARTITION BY t.Name ORDER BY t.Total DESC, t.Country) AS rn
FROM
(
    SELECT Name, Country, Status, COUNT(*) AS Total
    FROM table1
    GROUP BY Name, Country, Status
) t
WHERE rn <= 3

您可以使用以下查询:

;With CTE AS (
   SELECT Name, Country, Status,
          COUNT(*) OVER (PARTITION BY Name, Country) AS cnt
   FROM mytable
), CTE2 AS (
   SELECT Name, Country, Status, 
          DENSE_RANK() OVER (PARTITION BY Name ORDER BY cnt DESC, Country) AS seq
   FROM CTE
)
SELECT Name, Country, Status, COUNT(*) AS Total
FROM CTE2
WHERE seq <= 3
GROUP BY Name, Country, Status
ORDER BY Name, Country

在关系的情况下,查询会选择与其他国家/地区相比具有 'smallest' 名称的国家/地区。

怎么样:

select Top 3 with ties * FROM(
select Name, country, Status
, count(*) as total
, count(*) over (Partition BY Name, Country) as rank
from mytable
group by Name, Country, Status
) i 
order by i.rank desc

你能试试下面的SQL脚本吗

;with cte as (
    select *, COUNT(*) over (partition by country) cnt
    from table1
), t3 as (
    select distinct top 3 country, cnt
    from cte order by cnt desc
)
select distinct * 
from cte
inner join t3 on cte.country = t3.country

输出如下

使用下面的查询。

;WITH CTE
AS
(
    SELECT NAME,COUNTRY,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY COUNT(COUNTRY) DESC) ROWNO  FROM TBLCOUNTRY
    GROUP BY NAME,COUNTRY
)
SELECT C.NAME,C.COUNTRY,C.STATUS,COUNT(C.STATUS) TOTAL FROM TBLCOUNTRY C INNER JOIN CTE ON
C.NAME=CTE.NAME AND C.COUNTRY=CTE.COUNTRY AND CTE.ROWNO<=3
GROUP BY C.NAME,C.COUNTRY,C.STATUS
ORDER BY NAME,COUNTRY DESC, STATUS DESC