SELECT order_id,order_sn,total_amount FROM orderform WHERE order_id NOT IN (SELECT TOP 8 order_id FROM orderform);
假如有10条订单记录,查询后两条的记录。
那么,如果不知道有多少条记录,能不能查询出最后两条记录呢?
当然可以。对于不知道总记录数的情况,有多种方法可以查询最后两条记录。以下是几种常见数据库的解决方案:
1. SQL Server / Access 方案
使用子查询先获取总记录数,再计算偏移量:
sql
-- 方法1:使用子查询获取总记录数SELECT TOP 2 order_id, order_sn, total_amountFROM orderformORDER BY order_id DESC;-- 方法2:使用OFFSET(SQL Server 2012+)SELECT order_id, order_sn, total_amountFROM orderformORDER BY order_idOFFSET (SELECT COUNT(*) - 2 FROM orderform) ROWSFETCH NEXT 2 ROWS ONLY;
2. MySQL 方案
sql
-- 使用LIMIT和子查询SELECT order_id, order_sn, total_amountFROM orderformORDER BY order_id DESCLIMIT 2;-- 或者使用变量计算SELECT order_id, order_sn, total_amountFROM ( SELECT *, @row_num := @row_num + 1 AS row_number FROM orderform, (SELECT @row_num := 0) AS init ORDER BY order_id) AS tempWHERE row_number > (SELECT COUNT(*) - 2 FROM orderform);
3. PostgreSQL / Oracle 方案
sql
-- PostgreSQLSELECT order_id, order_sn, total_amountFROM orderformORDER BY order_id DESCLIMIT 2;-- OracleSELECT order_id, order_sn, total_amountFROM ( SELECT order_id, order_sn, total_amount FROM orderform ORDER BY order_id DESC)WHERE ROWNUM <= 2;
4. 通用方案(使用ROW_NUMBER)
sql
WITH numbered_orders AS ( SELECT order_id, order_sn, total_amount, ROW_NUMBER() OVER (ORDER BY order_id) AS rn, COUNT(*) OVER () AS total_count FROM orderform)SELECT order_id, order_sn, total_amountFROM numbered_ordersWHERE rn > total_count - 2;
你的原代码问题分析:
sql
SELECT order_id,order_sn,total_amountFROM orderform WHERE order_id NOT IN (SELECT TOP 8 order_id FROM orderform);
问题所在:
如果记录数少于8条,
TOP 8会返回所有记录,导致NOT IN结果为空如果记录数多于8条,只能获取最后N-8条,不一定是最后2条
依赖具体的order_id值,如果order_id不连续或有间隙会出错
最佳实践建议:
最简单可靠的方法(大多数数据库支持):
-- 倒序排序后取前2条 SELECT order_id, order_sn, total_amount FROM orderform ORDER BY order_id DESC LIMIT 2; -- SQL Server用 TOP 2,MySQL/Oracle/PostgreSQL用 LIMIT 2
这种方法:
✅ 不依赖总记录数
✅ 性能好(如果有索引)
✅ 代码简洁易懂
✅ 兼容性好
需要根据你使用的具体数据库选择相应的语法。
DESC是啥
DESC 是 DESCENDING(降序)的缩写,在 SQL 中用于指定排序方向。
基本含义
sql
ORDER BY column_name DESC -- 从大到小,从高到低,从新到旧ORDER BY column_name ASC -- 从小到大,从低到高,从旧到新(默认)
具体示例
1. 数值排序
sql
-- 降序:价格从高到低SELECT product_name, priceFROM productsORDER BY price DESC;-- 结果:100, 90, 80, 50, 30-- 升序(默认):价格从低到高SELECT product_name, priceFROM productsORDER BY price ASC;-- 结果:30, 50, 80, 90, 100
2. 日期排序
sql
-- 降序:最新的订单在前SELECT order_id, order_dateFROM orderformORDER BY order_date DESC;-- 结果:2026-04-15, 2026-04-14, 2026-04-13-- 升序:最早的订单在前SELECT order_id, order_dateFROM orderformORDER BY order_date ASC;-- 结果:2026-04-13, 2026-04-14, 2026-04-15
3. 字符串排序
sql
-- 降序:Z-ASELECT customer_nameFROM customersORDER BY customer_name DESC;-- 结果:张三, 李四, 王五... (按拼音或字母倒序)
查询最后两条记录的应用
sql
-- 方法1:按ID降序取前2条(最后2条)SELECT order_id, order_sn, total_amountFROM orderformORDER BY order_id DESC -- DESC 让最大的ID排在最前面LIMIT 2; -- 取前2条就是最后2条-- 如果需要按原始顺序显示(从小到大)SELECT order_id, order_sn, total_amountFROM ( SELECT order_id, order_sn, total_amount FROM orderform ORDER BY order_id DESC LIMIT 2) AS last_twoORDER BY order_id ASC; -- 再升序排列
多列排序
sql
-- 先按金额降序,金额相同再按订单号升序SELECT order_id, total_amount, order_dateFROM orderformORDER BY total_amount DESC, order_id ASC;
各数据库语法差异
| 数据库 | 降序取最后N条 |
|---|---|
| SQL Server | SELECT TOP 2 ... ORDER BY id DESC |
| MySQL | ... ORDER BY id DESC LIMIT 2 |
| PostgreSQL | ... ORDER BY id DESC LIMIT 2 |
| Oracle | ... ORDER BY id DESC FETCH FIRST 2 ROWS ONLY |
重要提示
⚠️ 注意区分:
DESC= DESCENDING(降序)DESC≠ DESCRIBE(某些数据库查看表结构的命令)
sql
-- 这是降序排序SELECT * FROM orders ORDER BY id DESC;-- 这是查看表结构(Oracle/MySQL支持)DESC orders; -- 等同于 DESCRIBE orders;
总结: 在查询最后两条记录的场景中,ORDER BY order_id DESC 就是为了让最大的 ID(最新的记录)排在前面,这样取前2条就是最后2条记录