当前位置: 首页 > 面试题库 >

SQL连接:选择一对多关系中的最后一条记录

查修谨
2023-03-14
问题内容

假设我有一个客户表和一个采购表。每次购买都属于一个客户。我想在一份SELECT声明中列出所有客户以及他们最近一次购买的清单。最佳做法是什么?关于建立索引有什么建议吗?

请在您的答案中使用这些表/列的名称:

  • customer:id,name
  • purchase: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上。

有些人使用子查询来代替我上面显示的解决方案,但是我发现我的解决方案可以更轻松地解决联系。



 类似资料:
  • 问题内容: 我有一个表,用于存储带有时间点的值: 每天可能有很多值,一天中也可能只有一个值。现在,我想获取最接近给定时间的给定时间范围(例如一个月)中每一天的值。我只想每天获得一个值(如果有当天的记录),或者没有值(如果没有记录)。我的数据库是PostgreSQL。我对此很坚持。我可以获取时间跨度中的所有值,并以编程方式为每天选择最接近的值,但这将意味着从数据库中提取大量数据,因为一天中可能有很多

  • 问题内容: 我有两个表: 帖子: 和标签: posts.tags和tags.tag都是文本类型。我想要的是从tag.tag到帖子中的行的关系,这样查询将给我对应于帖子1和2的行,查询给我2和3,给我1和3,依此类推。 我已经看过外键,但是我不确定这是我想要的。(老实说,我不确定它是做什么的)。据我所知,外键必须等于表的主键/唯一列。但是我想要的是诸如此类的所有行。我还希望能够获得以b开头的所有标签

  • 问题内容: 我有一张桌子,上面有几条记录。有一个ID字段。我想选择具有最新ID(即最高ID)的记录。 有任何想法吗? 问题答案:

  • 问题内容: 我正在寻找连接2个表并仅显示明细表的最后一条记录的正确SQL代码。 我有一个带有2个表的数据库, 每个交易都有多个评论,但是我想创建一个显示所有交易的视图,并且仅显示每个交易的最后一条评论(由CommentTime确定)字段 问题答案: 编辑:我没有足够接近地阅读初始问题,也没有注意到视图中需要所有DEALS行。以下是我的修改后的答案:

  • 问题内容: 使用以下模型: 如果我要查找包含至少一篇文章的订单操作,则可以按预期工作: 但是,如果要查找订单中所有商品的订单操作,正确的方法是什么? 引发错误(我理解为什么会这样)。 问题答案: 一个简单的解决方案: 这只是一个查询,但每篇文章都有一个内部联接。对于多篇文章,Willem更巧妙的解决方案应该会表现更好。

  • 问题内容: 仅使用SQL(MySQL),我想选择一个父子关系的最后一个子行,其中子行按时间戳排序。 例如,使用表和,我想分别获取每个表的最新记录(即带有最新时间戳的记录)。 产生类似于下表的结果集的最佳SQL语法是什么? 问题答案: