我有一份产品清单和一份类别清单
每个产品在特定时间内属于某些类别,
即,我们不时更换产品类别。
因此,为了保留日志,我有一个包含3个字段的表Product_Category
:
category_id [INT], product_id [INT], snapshot_date [DATE]
snapshot_date
是包含其所有产品的类别的最后更新时间
我想为给定的category_id(假设为category_id = 1
)选择所有产品ID,其中我只想要此类别的最后一个快照的产品
例如假设Product_Category中的数据:
+-------------+------------+---------------+
| category_id | product_id | snapshot_date |
+-------------+------------+---------------+
| 1 | 1 | 2015-01-01 | -----> old snapshot ignore it
| 1 | 2 | 2015-01-01 | -----> old snapshot ignore it
| 1 | 3 | 2015-01-01 | -----> old snapshot ignore it
| 1 | 1 | 2015-01-07 | -----> last snapshot for category 1, this is my target
| 1 | 5 | 2015-01-07 | -----> last snapshot for category 1, this is my target
| 1 | 7 | 2015-01-07 | -----> last snapshot for category 1, this is my target
| 2 | 5 | 2015-01-01 | -----> another category, old snapshot, ignore it
| 2 | 7 | 2015-01-07 | -----> another category, last snapshot, ignore it
| 2 | 3 | 2015-01-07 | -----> another category, last snapshot, ignore it
+-------------+------------+---------------+
鉴于category_id = 1
,我希望结果为
+------------+
| product_id |
+------------+
| 1 |
| 5 |
| 7 |
+------------+
这是我到目前为止所做的事情:
SELECT product_id
FROM Product_Category
WHERE category_id = 1
AND snapshot_date = (
SELECT MAX( snapshot_date )
FROM Product_Category
WHERE category_id = 1
);
进行嵌套选择是否有更好的解决方案?
PS,如果基于RDBMS的答案可能有所不同,我正在使用MySQL
答案 0 :(得分:1)
您的查询应该没问题。但是,某些版本的MySQL可能会为外部查询中处理的每一行运行子查询。解决方案是将子查询移动到FROM
子句:
SELECT pc.product_id
FROM Product_Category pc JOIN
(SELECT category_id, MAX( snapshot_date ) as maxsd
FROM Product_Category
WHERE category_id = 1
GROUP BY category_id
) pcmax
ON pc.category_id = pcmax.category_id and
pc.snapshot_date = pcmax.stampshot_date;
大多数数据库(包括我相信最新版本的MySQL)只会在查询中执行一次子查询。但是,此结构可确保子查询仅执行一次。