I have a question about writing a sub-query in Microsoft T-SQL. From the original table I need to return the name of the person with the second most pets. I am able to write a query that returns the number of perts per person, but I'm not sure how to write a subquery to return rank #2.
Original table:
+—————————-——+———-————-+
| Name | Pet |
+————————————+————-————+
| Kathy | dog |
| Kathy | cat |
| Nick | gerbil |
| Bob | turtle |
| Bob | cat |
| Bob | snake |
+—————————-——+—————-———+
I have the following query:
SELECT Name, COUNT(Pet) AS NumPets
FROM PetTable
GROUP BY Name
ORDER BY NumPets DESC
Which returns:
+—————————-——+———-————-+
| Name | NumPets |
+————————————+————-————+
| Bob | 3 |
| Kathy | 2 |
| Nick | 1 |
+—————————-——+—————-———+
The ANSI standard method is:
OFFSET 1 FETCH FIRST 1 ROW ONLY
However, most databases have their own syntax for this, using limit
, top
or rownum
. You don't specify the database, so I'm sticking with the standard.
You are using TSQL So:
WITH C AS (
SELECT COUNT(Pet) OVER (PARTITION BY Name) cnt
,Name
FROM PetTable
)
SELECT TOP 1 Name, cnt AS NumPets
FROM C
WHERE cnt = 2
This is how you could use ROW_NUMBER to get the result.
SELECT *
FROM(
SELECT ROW_NUMBER() OVER (ORDER BY COUNT(name) DESC) as RN, Name, COUNT(NAME) AS COUNT
FROM PetTable
GROUP BY Name
) T
WHERE T.RN = 2
In MSSQL you can do this:
SELECT PetCounts.Name, PetCounts.NumPets FROM (
SELECT
RANK() OVER (ORDER BY COUNT(Pet) DESC) AS rank,
Name, COUNT(Pet)as NumPets
FROM PetTable
GROUP BY Name
) AS PetCounts
WHERE rank = 2
This will return multiple rows if they have the same rank. If you want to return just one row you can replace RANK() with ROW_NUMBER()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.