select mo.id AS orderId, mo.requisition_id AS requisitionId, mo.order_number AS orderNumber, mo.order_date AS orderDate, msl.id as supplierId, msl.supplier_name AS supplierName, msl.supplier_end_name AS supplierEndName, msl.invoice_type AS invoiceType, su.user_name AS userName, msg.goods_id AS goodsId, mp.name AS productName, mo.payment_status AS paymentStatus, msg.transaction_amount AS transactionAmount, msg.executed_amount AS executedAmount, msg.unexecuted_amount AS unexecutedAmount, msg.invoice_amount AS invoiceAmount, msg.uninvoice_amount AS uninvoiceAmount, msg.accumulated_payments AS accumulatedPayments, mp.product_unit_id AS productUnitId, msg.execution_status_row AS executionStatusRow, msg.inventory_status AS inventoryStatus, msg.line_closed_status AS lineClosedStatus, mp.code AS productCode, mw.warehouse_name AS warehouseName, mwp.position_name AS positionName, msg.approve_number AS approveNumber, msg.unit_price_including_tax AS unitPriceIncludingTax, msg.tax_amount AS taxAmount, msg.price_tax AS priceTax, msg.line_remarks AS lineRemarks, msg.implemented_quantity AS implementedQuantity, msg.quantity_stock AS quantityStock, msg.un_executed_number AS unExecutedNumber, msg.un_stocked_quantity AS unStockedQuantity, msp.is_control AS isControl FROM medical_supplier_monad_goods msg LEFT JOIN medical_monad_order mo ON mo.id = msg.order_id AND msg.del_flag = 0 LEFT JOIN medical_supplier_list msl ON msl.id = mo.supplier_list_id AND msl.del_flag = 0 LEFT JOIN medical_supplier_parent msp ON msl.medical_supplier_parent_id = msp.id AND msp.del_flag = 0 LEFT JOIN sys_user su ON msl.user_id = su.user_id AND su.del_flag = 0 LEFT JOIN medical_product mp ON mp.name = msg.goods_id AND mp.del_flag = 0 GROUP BY mo.id, mo.requisition_id, mo.order_number; ORDER BY id DESC;我这里分组导致排序失效了 怎么解决
时间: 2025-03-21 21:08:18 浏览: 40
### SQL 查询中 GROUP BY 后 ORDER BY 排序失效的原因
在 MySQL 中,当使用 `GROUP BY` 进行分组时,MySQL 默认会选择每组中的任意一条记录作为代表。这种行为可能导致即使指定了 `ORDER BY` 子句,最终的结果仍然不符合预期顺序[^1]。
此外,在某些情况下,如果直接将 `ORDER BY` 放置在外层查询而未考虑内部数据的实际排列方式,则可能会因为分组操作覆盖掉排序效果而导致排序失效[^2]。
---
### 解决方案:通过子查询实现正确的排序与分组
为了确保分组后的结果能够按照指定字段正确排序,可以采用 **子查询** 的方法。以下是具体的解决方案:
#### 方法一:先排序后分组
可以通过嵌套子查询的方式,先对目标表按所需字段进行排序 (`ORDER BY`) ,然后再对外部查询应用 `GROUP BY` 。例如:
```sql
SELECT mo.id, mo.requisition_id
FROM (
SELECT *
FROM your_table_name
ORDER BY create_date DESC -- 按创建日期降序排序
) AS subquery
GROUP BY mo.id;
```
此方法的核心在于子查询部分已经完成了初步的排序工作,外层查询仅负责基于已排序的数据执行分组操作[^3]。
需要注意的是,上述语法可能不会完全生效于所有版本的 MySQL (尤其是较新版本)。这是因为自 MySQL 5.7 起,默认启用了严格模式(Strict Mode),这会阻止某些非标准的行为发生,比如依赖隐式的列值选取规则[^5]。
---
#### 方法二:利用窗口函数替代传统分组
对于更复杂的场景或者更高性能需求的应用场合,推荐改用窗口函数代替传统的 `GROUP BY` 结合 `ORDER BY` 方式。下面是一个例子展示如何获取每个请求单号下最新的记录条目:
```sql
WITH RankedRecords AS (
SELECT
id,
requisition_id,
create_date,
ROW_NUMBER() OVER(PARTITION BY requisition_id ORDER BY create_date DESC) as rn
FROM your_table_name
)
SELECT id, requisition_id, create_date
FROM RankedRecords
WHERE rn = 1;
```
这里运用了 `ROW_NUMBER()` 函数为每一组内的行分配唯一编号,并依据这些编号挑选出符合条件的第一项记录[^4]。
这种方法不仅解决了原始问题还提供了更大的灵活性去定义哪些特定条件下的记录应该被保留下来。
---
### 总结说明
无论是采取哪种策略都需要清楚理解自己业务逻辑以及所使用的数据库系统的特性差异。针对不同情况选择合适的手段才能既满足功能要求又能保持良好的运行效率。
---
阅读全文
相关推荐








删除订单 OrderController.java 文件信息如下: package order.controller; import … _______1______ public class OrderController { private OrderService orderService; @GetMapping("/__2__/{orderId}") public Order deleteOrder(@PathVariable("____3_____") Integer id) { Order order = orderService.deleteById(_______4_____); return order; } } OrderServiceImpl.java 文件信息如下: Package order.service.impl; import … ____5_____ public class OrderServiceImpl implements OrderService { ______6________ private OrderDao orderDao; @Override public Article deleteById(Integer orderId) { return______7____.deleteById(orderId); } } OrderDao.java 文件信息如下: package order.dao; import … ____8______ public interface OrderDao { Article deleteById(Integer orderId); } OrderMapper.xml 文件信息如下: <?xml version="1.0" encoding="UTF-8"?> <mapper namespace="____9_____"> <delete id="_____10_______" > delete from order where id = #{id} </select> </mapper>








