在我们的数据库中,我们有三个表:优惠、 sports,以及连接表 Offers_sports。我们想要检索包含一组给定体育项目的优惠,要求必须存在所有指定的体育项目,但也可能包含其他体育项目。
例如,考虑以下优惠:
如果我们查询包含“趴板运动”和“冲浪”的优惠,我们预计会收到“中度”和“全部”,但不会收到“轻度”。但是,我们当前的查询:
Offer.joins(:sports) .where(sports: { name: ["Bodyboarding", "Surfing"] }) .group("sports.name") .having("COUNT(distinct sports.name) = 2")
以及 SQL 等效项:
SELECT "offers".* FROM "offers" INNER JOIN "offers_sports" ON "offers_sports"."offer_id" = "offers"."id" INNER JOIN "sports" ON "sports"."id" = "offers_sports"."sport_id" WHERE "sports"."name" IN ('Bodyboarding', 'Surfing') GROUP BY sports.name HAVING COUNT(distinct sports.name) = 2;
不返回任何结果。
为了纠正这个问题,我们将查询修改为 group by优惠 ID 而不是运动名称:
SELECT o.* FROM sports s JOIN offers_sports os ON os.sport_id = s.id JOIN offers o ON os.offer_id = o.id WHERE s.name IN ('Bodyboarding', 'Surfing') GROUP BY o.id -- !! HAVING count(*) = 2;
或ActiveRecord:
class Offer < ActiveRecord::Base has_and_belongs_to_many :sports def self.includes_sports(*sport_names) joins(:sports) .where(sports: { name: sport_names }) .group('offers.id') .having("count(*) = ?", sport_names.size) end end
此修改可确保我们对结果进行适当分组并应用必要的过滤标准来检索包含指定体育项目的所需优惠。
以上是如何以多对多关系查询包含一组特定体育项目的商品?的详细内容。更多信息请关注PHP中文网其他相关文章!