首頁 > 資料庫 > mysql教程 > 如何以多對多關係查詢包含一組特定運動項目的商品?

如何以多對多關係查詢包含一組特定運動項目的商品?

DDD
發布: 2025-01-05 07:20:44
原創
951 人瀏覽過

How to Query for Offers Containing a Specific Set of Sports in a Many-to-Many Relationship?

SQL 錯誤:“其中連接集必須包含所有值,但可能包含更多”,用於優惠和體育過濾器

在我們的資料庫中,我們有三個表:優惠、 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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板