1

我有一个表,它通过外键与表users具有一对多的关系。也就是说,每个用户可以进行多次购买(或者可能没有,在这种情况下,他将在 user_purchases 表中没有条目)。user_purchasesuser_id

user_purchases这里只有一个感兴趣的领域,即purchase_date.

我正在尝试编写一个 Sequel ORM 语句,该语句将返回具有以下列的数据集:

  • 用户身份
  • 用户第二次购买的日期(如果存在)

因此,未进行至少 2 次购买的用户将不会出现在此数据集中。编写此 Sequel 声明的最佳方式是什么?

请注意,我正在寻找一个数据集,其中包含 >= 2 次购买的所有返回用户

谢谢!

为清晰而编辑

这是我为获取用户及其第一次购买日期而写的类似声明(而不是第二次购买日期,我在当前帖子中寻求帮助):

   DB[:users].join(:user_purchases, :user_id => :id)
              .select{[:user_id, min(:purchase_date)]}
              .group(:user_id)
4

3 回答 3

2

你似乎并不担心日期,只是计数所以

DB[:user_purchases].group_and_count(:user_id).having(:count > 1).all

将返回一个 user_ids 列表和计数(购买次数)> = 2。类似的东西

[{:count=>2, :user_id=>1}, {:count=>7, :user_id=>2}, {:count=>2, :user_id=>3}, ...]

如果您想获得用户,使用 Sequel 最简单的方法可能是仅提取 user_ids 列表并将其反馈到另一个查询中:

DB[:users].where(:id => DB[:user_purchases].group_and_count(:user_id).
    having(:count > 1).all.map{|row| row[:user_id]}).all

编辑:

我觉得应该有一种更简洁的方式,然后我看到了这个答案(来自续集作者 Jeremy Evans)对另一个问题的使用select_groupselect_morehttps ://stackoverflow.com/a/10886982/131226

这应该在没有子选择的情况下完成:

DB[:users].
  left_join(:user_purchases, :user_id=>:id).
  select_group(:id).
  select_more{count(:purchase_date).as(:purchase_count)}.
  having(:purchase_count > 1)

它生成这个 SQL

SELECT `id`, count(`purchase_date`) AS 'purchase_count' 
FROM `users` LEFT JOIN `user_purchases` 
ON (`user_purchases`.`user_id` = `users`.`id`) 
GROUP BY `id` HAVING (`purchase_count` > 1)"
于 2012-11-13T05:26:18.323 回答
0

通常,这可能是您需要的 SQL 查询:

SELECT u.id, up1.purchase_date FROM users u
LEFT JOIN user_purchases up1 ON u.id = up1.user_id
LEFT JOIN user_purchases up2 ON u.id = up2.user_id AND up2.purchase_date < up1.purchase_date
GROUP BY u.id, up1.purchase_date
HAVING COUNT(up2.purchase_date) = 1;

如果您没有得到更好的答案,请尝试将其转换为续集。

于 2012-11-02T17:16:19.577 回答
0

如果您在查询中执行 an ,则用户第二次购买的日期将是检索到的第二行order_by(:purchase_date)

要访问它,请执行 alimit(2)将查询限制为两个结果,然后取[-1](or last) 一个。因此,如果您不使用模型并且仅使用数据集,并且知道user_id您感兴趣的内容,那么您的(未经测试的)查询将是:

DB[:user_purchases].where(:user_id => user_id).order_by(:user_purchases__purchase_date).limit(2)[-1]

以下是 Sequel 控制台的一些输出:

DB[:user_purchases].where(:user_id => 1).order_by(:purchase_date).limit(2).sql
=> "SELECT * FROM user_purchases WHERE (user_id = 1) ORDER BY purchase_date LIMIT 2"

添加适当的select子句:

.select(:user_id, :purchase_date)

你应该完成:

DB[:user_purchases].select(:user_id, :purchase_date).where(:user_id => 1).order_by(:purchase_date).limit(2).sql
=> "SELECT user_id, purchase_date FROM user_purchases WHERE (user_id = 1) ORDER BY purchase_date LIMIT 2"
于 2012-11-02T17:20:43.653 回答