2015-03-03 44 views
2

我有一个关于在Microsoft T-SQL中编写子查询的问题。从原始表中,我需要返回第二大宠物的人的姓名。我能够编写一个查询返回每人的perts数量,但我不确定如何编写一个子查询返回排名#2。SQL子查询返回等级2

原始表:

+—————————-——+———-————-+ 
| Name  | Pet | 
+————————————+————-————+ 
| Kathy  | dog | 
| Kathy  | cat | 
| Nick  | gerbil | 
| Bob  | turtle | 
| Bob  | cat | 
| Bob  | snake | 
+—————————-——+—————-———+ 

我有以下查询:

SELECT Name, COUNT(Pet) AS NumPets 
FROM PetTable 
GROUP BY Name 
ORDER BY NumPets DESC 

将返回:

+—————————-——+———-————-+ 
| Name  | NumPets | 
+————————————+————-————+ 
| Bob  | 3  | 
| Kathy  | 2  | 
| Nick  | 1  | 
+—————————-——+—————-———+ 
+0

你的RDBMS的方式是什么? – potashin 2015-03-03 01:08:03

+2

如果2个所有者拥有最大数量的宠物 - 是下一个要归还的宠物吗?如果有几个第二名的地方呢? – zerkms 2015-03-03 01:10:35

+0

如果您使用的是MS SQL Server,则可以使用['ROW_NUMBER'](https://msdn.microsoft.com/en-us/library/ms186734.aspx)分配rownumber,然后选择row = 2。 – 2015-03-03 01:15:29

回答

0

您正在使用TSQL所以:

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 
0

ANSI标准方法是:

OFFSET 1 FETCH FIRST 1 ROW ONLY 

但是,大多数数据库都有自己的语法,使用limit,toprownum。你不指定数据库,所以我坚持使用标准。

0

这是你如何使用ROW_NUMBER得到结果。

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 
0

在MSSQL中,你可以这样做:

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 

这将返回多行,如果它们具有相同的等级。如果你想只返回一行,你可以用ROW_NUMBER()替换RANK()