【发布时间】:2016-11-30 03:43:06
【问题描述】:
我有三个表offers、sports 和连接表offers_sports。
class Offer < ActiveRecord::Base
has_and_belongs_to_many :sports
end
class Sport < ActiveRecord::Base
has_and_belongs_to_many :offers
end
我想选择包含给定运动名称数组的报价。它们必须包含所有sports,但可能有更多。
假设我有这三个报价:
light:
- "Yoga"
- "Bodyboarding"
medium:
- "Yoga"
- "Bodyboarding"
- "Surfing"
all:
- "Yoga"
- "Bodyboarding"
- "Surfing"
- "Parasailing"
- "Skydiving"
给定数组["Bodyboarding", "Surfing"],我想得到medium 和all,但不是light。
我尝试了类似this answer 的方法,但结果中的行数为零:
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;
一个 ActiveRecord 答案会很好,但我会满足于 SQL,最好是兼容 Postgres。
数据:
offers
======================
id | name
----------------------
1 | light
2 | medium
3 | all
4 | extreme
sports
======================
id | name
----------------------
1 | "Yoga"
2 | "Bodyboarding"
3 | "Surfing"
4 | "Parasailing"
5 | "Skydiving"
offers_sports
======================
offer_id | sport_id
----------------------
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
3 | 3
3 | 4
3 | 5
4 | 3
4 | 4
4 | 5
【问题讨论】:
-
SQL 是否有效?看起来是正确的。
-
返回 0 行。 @GordonLinoff
-
你快到了:按“优惠”字段分组(用明确的字段名称替换 * 并重复分组依据)。您现在按 sports.name 分组,自然,每个 sports.name 的不同数量的 sports.name 始终为 1。
-
@HenkKok 仍然给出 0 行:
SELECT offers.name, offers.id, sports.id 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 offers.name, offers.id, sports.name HAVING COUNT(distinct sports.name) = 2 -
那是因为你还在group by中加入了sports.name,那一栏必须从group by中去;此外,sports.id 必须从 SELECT 子句中删除。如果您在最终结果中需要优惠和运动,请首先选择优惠(与所有 2 项运动相关联),然后将该选择用作内联视图以加入运动。
标签: sql ruby-on-rails postgresql rails-activerecord relational-division