Mysql从表中选择每个唯一location_id和产品的日期最大值

时间:2014-10-10 11:58:04

标签: php mysql

我有一张表 - 记录 - 看起来像这样

id | location_id | product | stock | date  
===|=============|=========|=======|======
1  | Bakery 1    |  cake   |  21   | 2
2  | Bakery 1    |  bread  |  23   | 2
3  | Bakery 2    |  cake   |  21   | 2
4  | Bakery 2    |  bread  |  21   | 2
5  | Bakery 1    |  cake   |  21   | 3
6  | Bakery 1    |  bread  |  23   | 3
7  | Bakery 2    |  cake   |  21   | 3
8  | Bakery 2    |  bread  |  21   | 3
9  | Bakery 1    |  cake   |  21   | 4
10 | Bakery 1    |  bread  |  23   | 4
11 | Bakery 2    |  bread  |  23   | 4

对于每个位置和每个产品,我想选择具有最高日期值的行。这看起来像是

id | location_id | product | stock | date  
===|=============|=========|=======|======
7  | Bakery 2    |  cake   |  21   | 3
9  | Bakery 1    |  cake   |  21   | 4
10 | Bakery 1    |  bread  |  23   | 4
11 | Bakery 2    |  bread  |  23   | 4

如何使用一个查询执行此操作?我可以循环遍历所有位置和所有产品并构建查询,但它耗费更多时间和内存?

2 个答案:

答案 0 :(得分:2)

select r1.*
from records r1
join
(
  select location_id, product, max(date) as date
  from records
  group by location_id, product
) r2 on r1.location_id = r2.location_id 
    and r1.product = r2.product
    and r1.date = r2.date

答案 1 :(得分:1)

如果满足以下条件,您可以使用id

非常有效地完成此项工作
  1. 您的id列是自动增量
  2. date列代表当前日期:即您永远不会插入回溯记录。
  3. 您没有更新date
  4. 如果这些条件为真,则表示唯一标识符id可用作每条记录的非唯一值date的代理。值date更高的行始终保证具有更高的id值。

    如果你能做到这一点,你可以使你的查询表现得非常好。

    首先,您创建一个子查询,以获取每个位置和产品组合的最新行的id

    SELECT MAX(id)
      FROM records
     GROUP BY location_id, date
    

    然后使用该组id值从表中提取正确的记录

    SELECT *
      FROM records
     WHERE id IN (
                    SELECT MAX(id)
                     FROM records
                    GROUP BY location_id, date
                  )
    ORDER BY location_id, product