SQL技术问询:获取每种产品最早已完成订单及语法报错解决
问题分析与解决方案
错误原因
你写的and (productname = UNIQUE)是语法错误,UNIQUE是用于定义字段唯一性约束的关键字,不能用在WHERE子句里作为筛选条件,这就是报错的直接原因。
正确实现方法
要实现每种产品取最早的已完成订单(且订单更新时间在当天之后),可以用以下两种方法:
方法1:窗口函数ROW_NUMBER()(推荐,保留全量字段)
适合SQL Server、MySQL 8.0+、PostgreSQL等支持窗口函数的数据库:
WITH RankedOrders AS ( SELECT [orderID], [productname], [orderStatus], [customerID], [lastUpdateTime], -- 按产品分组,按更新时间升序排名,最早的订单排第1 ROW_NUMBER() OVER (PARTITION BY [productname] ORDER BY [lastUpdateTime] ASC) AS rn FROM [Orders] WHERE lastUpdateTime > CAST(GETDATE() AS DATE) AND orderStatus = 'filled' ) SELECT [orderID], [productname], [orderStatus], [customerID], [lastUpdateTime] FROM RankedOrders WHERE rn = 1; -- 取每组排名第1的订单(最早的)
方法2:子查询+关联查询
如果数据库不支持窗口函数,可以用这种方式:
SELECT o.[orderID], o.[productname], o.[orderStatus], o.[customerID], o.[lastUpdateTime] FROM [Orders] o INNER JOIN ( -- 先找出每种产品的最早已完成订单时间 SELECT [productname], MIN([lastUpdateTime]) AS earliestTime FROM [Orders] WHERE lastUpdateTime > CAST(GETDATE() AS DATE) AND orderStatus = 'filled' GROUP BY [productname] ) t ON o.[productname] = t.[productname] AND o.[lastUpdateTime] = t.earliestTime WHERE o.orderStatus = 'filled' AND o.lastUpdateTime > CAST(GETDATE() AS DATE);
说明
- 两种方法都会返回每种产品符合条件的最早已完成订单,满足你期望的3行结果(对应苹果、香蕉、橙子各一行)。
- 原代码中的
lastUpdateTime > cast( getdate() as date )会筛选出当天0点之后更新的订单,如果你的需求是“首个已完成订单”不受时间范围限制,可以去掉这个条件。
内容的提问来源于stack exchange,提问作者Bootshoe
相关产品推荐
相关产品推荐

