SELECT TOP N 问题

博客介绍了TOP N问题,即SELECT中选择按某列排序后TOP N的纪录,分仅返回N条和包含等值纪录两种情况。还给出了SQL SERVER 7、ORACLE 8i、DB2实现TOP N查询的语句,同时指出部分错误用法,最后给出测试示例。
简单地说,TOP N问题就是:在SELECT中,仅选择按照某(些)列排序后TOP N的纪录. 考虑到等值问题,又可以分为两种: 一是仅仅返回N条纪录(M 1), 二是还包括所有于第N条等值的纪录(M 2). 当然最内层的子查询也可以有其他的子句, 或者TOP N也可以应用在没有ORDER BY的情况下,这样更简单.

1. SQL SERVER 7: 用 TOP N (WITH TIES)
M1:
SELECT TOP N * FROM MYTABLE ORDER BY ORD_COL;

M2:
SELECT TOP N??WITH TIES * FROM MYTABLE ORDER BY ORD_COL;
注: SQL SERVER 7提供了PERCENT N WITH TIES, ACCESS 中提供了TOP N,但含义是M 2.

2. ORACLE 8i: 用 ROWNUM<=N
M1:
SELECT * FROM
?????( SELECT * FROM MYTABLE ORDER BY ORD_COL DESC)
WHERE ROWNUM<=N
M2:
SELECT * FROM MYTABLE WHERE ORD_COL>=
???(SELECT MIN(ORD_COL) FROM
????????( SELECT * FROM MYTABLE ORDER BY ORD_COL DESC)
????WHERE ROWNUM<=N)
ORDER BY ORD_COL DESC
注意以下两种错误用法:
WRONG 1:
SELECT * FROM MYTABLE
WHERE??ROWID<=N
ORDER BY ORD_COL DESC;

WRONG 2:(因为WHERE ROWNUM<=N 在ORDER BY 前执行)
SELECT * FROM MYTABLE
WHERE??ROWNUM<=N
ORDER BY ORD_COL DESC;

3: DB2
用FETCH FIRST N ROWS ONLY
M1:
SELECT * FROM MYTABLE
ORDER BY ORD_COL DESC
FETCH FIRST N ROWS ONLY
M2:
没有找到,因为DB2不允许在FROM中嵌套有ORDER BY子句的子查询.

还不清楚ORACLE的M 2有没有更好的办法,以及其他的DBMS如何实现TOP N操作,请其他朋友补充.
----------------------------------------------------------------------------------
各语句已经测试过, EXAMPLE:
create table mytable(mykey int, ord_col int);
insert into mytable values(1, 100);
insert into mytable values(2, 100);
insert into mytable values(3, 99);
insert into mytable values(4, 101);
insert into mytable values(5, 101);

### SQL 实现 Top N 查询 示例 语法 在 SQL 中,不同的数据库管理系统(DBMS)对实现 Top N 查询的支持有所不同。以下将分别介绍 MySQLSQL Server 的实现方式。 #### MySQL 中的 Top N 查询 MySQL 不支持 `SELECT TOP N` 的语法,但可以通过 `LIMIT` 子句实现类似的功能。`LIMIT` 子句用于限制查询结果返回的行数,并通常与 `ORDER BY` 子句结合使用以确保返回的结果是有序的。 以下是 MySQL 中实现 Top N 查询的基本语法: ```sql SELECT * FROM table_name ORDER BY column_name [ASC|DESC] LIMIT n; ``` - `table_name`:要查询的表名。 - `column_name`:用于排序的列名。 - `[ASC|DESC]`:指定升序(ASC)或降序(DESC)排序,默认为升序。 - `n`:需要返回的前 N 条记录的数量。 **示例 1**:查询 `students` 表中成绩最高的前 5 名学生[^4]。 ```sql SELECT * FROM students ORDER BY score DESC LIMIT 5; ``` #### SQL Server 中的 Top N 查询 SQL Server 支持 `SELECT TOP N` 的语法,可以直接用于限制返回的行数。为了确保结果的顺序,通常也需要与 `ORDER BY` 子句结合使用。 以下是 SQL Server 中实现 Top N 查询的基本语法: ```sql SELECT TOP n column_name(s) FROM table_name ORDER BY column_name [ASC|DESC]; ``` - `n`:需要返回的前 N 条记录的数量。 - 其他参数含义与 MySQL 类似。 **示例 2**:查询 `employees` 表中工资最高的前 3 名员工[^3]。 ```sql SELECT TOP 3 * FROM employees ORDER BY salary DESC; ``` #### 分组查询中的 Top N 对于分组查询中的 Top N 问题,例如查询每个类别中价格最高的前 3 个商品,可以使用子查询或窗口函数来实现。 **方法一:子查询** 通过子查询计算每种类别中小于当前商品价格的商品数量,并限制该数量小于 N。 以下是 MySQL 中的实现示例[^2]: ```sql SELECT goods_id, goods_name, cat_id, shop_price FROM goods WHERE ( SELECT COUNT(*) FROM goods g2 WHERE goods.shop_price < g2.shop_price AND goods.cat_id = g2.cat_id ) < 3 ORDER BY cat_id, shop_price DESC; ``` **方法二:窗口函数(适用于支持窗口函数的数据库,如 SQL Server 或 MySQL 8.0+)** 使用 `ROW_NUMBER()` 窗口函数为每种类别的商品按价格排序,并筛选出排名前 N 的商品。 以下是 SQL Server 中的实现示例: ```sql WITH RankedGoods AS ( SELECT goods_id, goods_name, cat_id, shop_price, ROW_NUMBER() OVER (PARTITION BY cat_id ORDER BY shop_price DESC) AS rn FROM goods ) SELECT goods_id, goods_name, cat_id, shop_price FROM RankedGoods WHERE rn <= 3; ``` ### 注意事项 1. 在 MySQL 中,`LIMIT` 是实现 Top N 查询的主要手段。 2. 在 SQL Server 中,`SELECT TOP N` 是更直接的方式。 3. 对于分组查询中的 Top N 问题,可以使用子查询或窗口函数,具体取决于所使用的数据库版本和支持的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值