mysql order by created_at desc 在数据库层排序,要求字段为 datetime/timestamp 类型且非空;需加 limit 防卡顿,索引与主键分页更关键。

MySQL 查询里用 ORDER BY created_at DESC 最直接
PHP 本身不负责排序,真正排序发生在数据库层。订单时间字段(比如 created_at)必须是 DATETIME 或 TIMESTAMP 类型,否则 ORDER BY 会按字符串规则排,导致 “2024-1-10” 排在 “2024-1-2” 前面这种错误。
常见写法:
SELECT * FROM orders ORDER BY created_at DESC LIMIT 20;
- 加
DESC是为了从最新订单开始显示,用户更习惯 - 如果字段名是
order_time或add_time,记得替换成实际字段名 - 没加
LIMIT的话,大数据量时页面可能卡死或超内存
PHP 中用 usort() 二次排序只适合小数据
只有在已查出全部订单(比如缓存里取的数组)、且数量很少(
示例(假设订单数组叫 $orders,每项含 created_at 字符串):
usort($orders, function($a, $b) {
return strtotime($b['created_at']) - strtotime($a['created_at']);
});
-
strtotime()能处理常见格式如"2024-03-15 14:22:08",但对"15/03/2024"这类格式会失败 - 别用
date_create()在循环里反复调用,性能差;提前转成时间戳存到数组里更稳 - 注意时区:PHP 默认时区和 MySQL 的
time_zone不一致时,strtotime()解析结果可能和数据库值对不上
分页 + 排序组合容易漏掉 ORDER BY 的唯一性保障
用 LIMIT 20,20 分页时,如果多条订单的 created_at 完全相同(比如同一秒内创建多个),MySQL 可能返回不稳定顺序,翻页时出现重复或丢失记录。
- 解决办法是在
ORDER BY后追加主键,例如:ORDER BY created_at DESC, id DESC - 不能只靠
id排序,因为订单未必按 ID 递增时间生成(比如有延迟写入、分库分表) - 如果用 Laravel Eloquent,写法是:
Order::orderBy('created_at', 'desc')->orderBy('id', 'desc')->paginate(20)
时间字段为空或为 0000-00-00 00:00:00 会导致排序异常
MySQL 默认允许 0000-00-00,但它比任何合法时间都“小”,ORDER BY ... DESC 时会出现在列表最底部,用户看不到,还可能干扰分页总数计算。
- 建表时把时间字段设为
NOT NULL DEFAULT CURRENT_TIMESTAMP,从源头避免空值 - 查询前加过滤:
WHERE created_at != '0000-00-00 00:00:00' AND created_at IS NOT NULL - 如果历史数据已存在脏值,先用
UPDATE orders SET created_at = NOW() WHERE created_at = '0000-00-00 00:00:00';修复
实际业务里,时间字段类型是否规范、是否加了索引、分页时有没有补主键,这三点出问题的概率远高于 PHP 代码写错。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











