假设我有一张客户表和一张采购表。每次购买都属于一位客户。我想获得所有客户的列表以及他们最后一次购买的商品SELECT
陈述。最佳实践是什么?关于建立索引有什么建议吗?
请在您的答案中使用这些表/列名称:
- 顾客:
id
, name
- 购买:
id
, customer_id
, item_id
, date
在更复杂的情况下,通过将最后一次购买放入客户表来对数据库进行非规范化是否(从性能角度)有益?
如果(购买)id
保证按日期排序,可以通过使用类似的东西来简化语句LIMIT 1
?
这是一个例子greatest-n-per-group
StackOverflow 上经常出现的问题。
以下是我通常建议解决该问题的方法:
SELECT c.*, p1.*
FROM customer c
JOIN purchase p1 ON (c.id = p1.customer_id)
LEFT OUTER JOIN purchase p2 ON (c.id = p2.customer_id AND
(p1.date < p2.date OR (p1.date = p2.date AND p1.id < p2.id)))
WHERE p2.id IS NULL;
说明:给定一行p1
,不应该有行p2
与同一客户和较晚的日期(或者在平局的情况下,较晚的日期)id
)。当我们发现这是真的时,那么p1
是该客户最近一次购买的商品。
关于索引,我会在中创建一个复合索引purchase
在列上(customer_id
, date
, id
)。这可能允许使用覆盖索引来完成外连接。请务必在您的平台上进行测试,因为优化取决于实现。使用 RDBMS 的功能来分析优化计划。例如。EXPLAIN
在 MySQL 上。
有些人使用子查询而不是我上面展示的解决方案,但我发现我的解决方案可以更轻松地解决关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)