Rails/SQL - 如何按组中的不同值进行过滤
Rails/SQL - How to filter by distinct value in a group
我在 Rails 工作,但 SQL 中的回答同样有用。假设我有 table 的用户和 table 的购买。我想找到只购买过商品 A 的用户。我希望使用如下查询:
User.joins(:purchases).group(:id).having("DISTINCT(item) = 'A'").pluck(:id)
这是我需要回答的问题的简化,但这个分组问题是我的主要障碍。出于这个原因,我希望得到一个逻辑上非常相似的答案,因为其他解决方法可能不适用。
这在 Rails 中有效吗?
User.joins(:purchases).group(:id).having("MIN(item) = MAX(item) AND MIN(item) = 'A'").pluck(:id)
此短语为:只有一个不同的值(因为 MIN()
和 MAX()
相等),即 'A'
.
或者:
having("MAX(CASE WHEN item <> 'A' THEN 1 ELSE 0 END) = 0")
代表:除了 'A'
.
没有其他值
在 having
中,您只能在进行分组的列上使用聚合函数(例如 having count(id) > 2
)或表达式,例如having("id > 1")
.
因此,根据您的数据库,您可能会尝试找到一个聚合函数,用于识别每个 ID 分组中项目的存在。
对于 PostgreSql,它类似于(尚未测试):
...
GROUP BY id
HAVING 'A' = ANY(ARRAY_AGG(item))
我在 Rails 工作,但 SQL 中的回答同样有用。假设我有 table 的用户和 table 的购买。我想找到只购买过商品 A 的用户。我希望使用如下查询:
User.joins(:purchases).group(:id).having("DISTINCT(item) = 'A'").pluck(:id)
这是我需要回答的问题的简化,但这个分组问题是我的主要障碍。出于这个原因,我希望得到一个逻辑上非常相似的答案,因为其他解决方法可能不适用。
这在 Rails 中有效吗?
User.joins(:purchases).group(:id).having("MIN(item) = MAX(item) AND MIN(item) = 'A'").pluck(:id)
此短语为:只有一个不同的值(因为 MIN()
和 MAX()
相等),即 'A'
.
或者:
having("MAX(CASE WHEN item <> 'A' THEN 1 ELSE 0 END) = 0")
代表:除了 'A'
.
在 having
中,您只能在进行分组的列上使用聚合函数(例如 having count(id) > 2
)或表达式,例如having("id > 1")
.
因此,根据您的数据库,您可能会尝试找到一个聚合函数,用于识别每个 ID 分组中项目的存在。 对于 PostgreSql,它类似于(尚未测试):
...
GROUP BY id
HAVING 'A' = ANY(ARRAY_AGG(item))