2 votes

Deuxième niveau Top N du serveur SQL

J'ai une table avec des noms, des pays et des statuts. Je veux obtenir le total en regroupant les noms et les statuts mais en obtenant seulement les 3 premiers pays.

Ma 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   |
+------+---------+--------+

Sortie souhaitée :

+------+---------+--------+-------+
| 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 |
+------+---------+--------+-------+

J'ai essayé la requête suivante mais elle n'a pas donné le résultat que je recherche.

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

2voto

Giorgos Betsos Points 61197

Vous pouvez utiliser la requête suivante :

;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

En cas d'égalité, la requête choisit le pays dont le nom est le plus "petit" par rapport aux autres pays.

1voto

Tim Biegeleisen Points 53335

Votre requête initiale allait dans la bonne direction (je l'ai même utilisée pour déterminer le résultat que vous vouliez). Cependant, le résultat que vous souhaitez obtenir est le résultat de plusieurs agrégations, et non d'une seule fonction analytique. Dans la requête ci-dessous, j'agrège d'abord pour obtenir les totaux, puis j'utilise le rang pour retenir les 3 premiers groupes. En cas d'égalité, cette requête choisit le pays qui vient en premier par ordre alphabétique.

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

0voto

D Coder Points 512

Essayez celui-ci

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

0voto

artm Points 7841

Pourquoi pas :

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

0voto

Eralper Points 364

Pourriez-vous s'il vous plaît essayer ci-dessous SQL script

;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

La sortie est la suivante

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X