二级 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
我有一个 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