简体   繁体   English

MySQL 我怎样才能 SELECT MIN 从哪里得到结果

[英]MySQL How Can I SELECT MIN From Where result

I created a query to select the minimum OrderDate of 2020 or 2019 but I always get the result of 2019 when I use 'OR', I have tried to use the case too but always the same result..我创建了一个查询 select,最小订单日期为 2020 年或 2019 年,但当我使用“或”时,我总是得到 2019 年的结果,我也尝试过使用这种情况,但结果总是相同。

so what I want is to select the minimum orderDate of 2020 but when there is no order in 2020 then select the orders of 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;

这是结果

How about using direct date comparisons for the filtering.如何使用直接日期比较进行过滤。 Then use COALESCE() :然后使用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;

The COALESCE() first looks for the minimum date in 2020. If not present, it uses the minimum for 2019. COALESCE()首先查找 2020 年的最小日期。如果不存在,它将使用 2019 年的最小日期。

I changed the comparison logic for two reasons.我出于两个原因更改了比较逻辑。 First, the YEAR() function should operate on dates and '2020' is not a date.首先, YEAR() function 应该在日期上运行,而'2020'不是日期。 Second, direct comparisons are more efficient -- they help the optimizer use indexes and partitions for instance.其次,直接比较更有效——例如,它们有助于优化器使用索引和分区。

EDIT:编辑:

Actually, another interesting way to think about the problem is that you want the maximum of the minimum order dates for the two years.实际上,考虑该问题的另一种有趣方式是,您需要这两年中最短订单日期中的最大值。 That suggests two levels of aggregation:这表明有两个聚合级别:

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;

I should note that the first version will be more efficient.我应该注意到第一个版本会更有效率。

Here is a way to do this using analytic functions, along with union:下面是使用解析函数和 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;

The logic here is that we find, for each employee, the earliest order dates for both 2019 and 2020. In the first CTE, this is done, and we also assign a priority to each year, with 2020 having the higher priority (1 vs. 2, with 1 coming first logically).这里的逻辑是,我们为每个员工找到 2019 年和 2020 年的最早订单日期。在第一个 CTE 中,这样做了,我们还为每年分配了一个优先级,2020 年具有更高的优先级(1 对. 2,逻辑上 1 排在第一位)。 Then, we assign a row number to each of the 1 or 2 employee records from 2019/2020, and retain the highest priority record.然后,我们为 2019/2020 的 1 或 2 个员工记录中的每一个分配一个行号,并保留最高优先级的记录。 Note that for employees having both years, 2020 would be retained, while 2019 would be retained in the event that an employee has no 2020 data.请注意,对于拥有这两个年份的员工,将保留 2020 年,而如果员工没有 2020 年的数据,则将保留 2019 年。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM