我该如何编写这个MySQL查询?

时间:2012-10-12 01:42:15

标签: mysql

我们有一个系统,用户向我们发送货物袋。

我正在尝试弄清楚如何使用计算字段为用户提供他们发送第3件商品的日期。历史记录表上指示此事件的状态为“已处理”。如果我想获得特定包的收到日期,我会写:

SELECT bags.created_at FROM history 
WHERE history.state='received' AND history.bag_id LIMIT 1

以下是我们的表格:

users
  id

bags
  user_id

history
  state
  bag_id
  created_at

最终目标是一个选择查询,它为我们提供用户记录并添加“字段”3rd_bag_received_at

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您可以group by user_id,然后添加having子句以仅包含count(distinct bag_id) >= 3的用户。

然后limit到3,order by获取最新日期max(created_at)

这有帮助吗?

实现看起来像这样:

select 
 user.id, 
 max(history.created_at) as third_bag_received_at

from
(

 select 
   user.id, 
   max(history.created_at)

 from 
   users

   inner join bags
   on user.id = bags.user_id

   inner join history
   on bags.id = history.bag_id

 where history.state = 'processed'

 group by
   user.id

 having
   count(history.bag_id >= 3)

 limit 3

 order by 2 -- does this work in mySql? (It means "column 2" in MS SQL)
)

Limit 1

编辑:如何解决计算列中其他表的连接/聚合问题:

我可能会创建一个视图,其中包含此要求所需的任何信息,包括基于此查询的third_bag_received列,而不是将其添加为计算列。

但是如果你确实需要在桌面上将其作为计算列实现:

我建议创建一个接受user.id作为输入的用户函数,并返回third_bag_received_at的值(同样,基于上述查询的逻辑)。

然后从计算列中调用此函数。请参阅this SO question上的@ user10635答案。

答案 1 :(得分:0)

我只是开发了一些更简洁的Sepster答案。 这个问题是不稳定的,因为它并没有说餐袋有任何叫做bags.id的领域,我不得不补偿。

SELECT users.id, MAX(history.created_at) as 3rd_bag_received_at
FROM users LEFT JOIN bags ON (users.id=bags.user_id)
LEFT JOIN history ON(bags.id = history.bag_id)
WHERE history.state='received'
GROUP BY users.id
HAVING COUNT(history.bag_id) >= 3;