[英]MySQL How Can I SELECT MIN From Where result
我创建了一个查询 select,最小订单日期为 2020 年或 2019 年,但当我使用“或”时,我总是得到 2019 年的结果,我也尝试过使用这种情况,但结果总是相同。
所以我想要的是 select 2020 年的最小订单日期,但是当 2020 年没有订单时,那么 select 是 2019 年的订单。
SELECT o.EmployeeID , min(o.OrderDate) as minOrderDate
FROM Orders o
where o.EmployeeID = 1 and (year(o.OrderDate) = year('2020') or year(o.OrderDate) = year('2019'))
group by o.EmployeeID;
如何使用直接日期比较进行过滤。 然后使用COALESCE()
:
SELECT o.EmployeeID,
COALESCE(MIN(CASE WHEN o.OrderDate >= '2020-01-01' THEN o.OrderDate END),
MIN(o.OrderDate)
) as minOrderDate
FROM Orders o
WHERE o.EmployeeID = 1 AND
o.OrderDate >= '2019-01-01' AND
o.OrderDate < '2021-01-01'
GROUP BY o.EmployeeID;
COALESCE()
首先查找 2020 年的最小日期。如果不存在,它将使用 2019 年的最小日期。
我出于两个原因更改了比较逻辑。 首先, YEAR()
function 应该在日期上运行,而'2020'
不是日期。 其次,直接比较更有效——例如,它们有助于优化器使用索引和分区。
编辑:
实际上,考虑该问题的另一种有趣方式是,您需要这两年中最短订单日期中的最大值。 这表明有两个聚合级别:
SELECT EmployeeId, MAX(min_orderDate) as min_orderDate
FROM (SELECT o.EmployeeID, MIN(o.OrderDate) as min_orderDate
FROM Orders o
WHERE o.EmployeeID = 1 AND
o.OrderDate >= '2019-01-01' AND
o.OrderDate < '2021-01-01'
GROUP BY o.EmployeeID, YEAR(o.OrderDate)
) ey
GROUP BY EmployeeId;
我应该注意到第一个版本会更有效率。
下面是使用解析函数和 union 来做到这一点的方法:
WITH cte AS (
SELECT EmployeeID, MIN(OrderDate) AS minOrderDate, 1 AS priority
FROM Orders
WHERE YEAR(OrderDate) = 2020
GROUP BY EmployeeID
UNION ALL
SELECT EmployeeID, MIN(OrderDate), 2
FROM Orders
WHERE YEAR(OrderDate) = 2019
GROUP BY EmployeeID
),
cte2 AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY priority) rn
FROM cte
)
SELECT EmployeeID, minOrderDate
FROM cte2
WHERE rn = 1
ORDER BY EmployeeID;
这里的逻辑是,我们为每个员工找到 2019 年和 2020 年的最早订单日期。在第一个 CTE 中,这样做了,我们还为每年分配了一个优先级,2020 年具有更高的优先级(1 对. 2,逻辑上 1 排在第一位)。 然后,我们为 2019/2020 的 1 或 2 个员工记录中的每一个分配一个行号,并保留最高优先级的记录。 请注意,对于拥有这两个年份的员工,将保留 2020 年,而如果员工没有 2020 年的数据,则将保留 2019 年。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.