首页 > 数据库 > mysql教程 > 如何在 SQL 中选择包含所有给定体育项目(但可能更多)的报价?

如何在 SQL 中选择包含所有给定体育项目(但可能更多)的报价?

Mary-Kate Olsen
发布: 2024-12-27 13:49:10
原创
325 人浏览过

How to Select Offers Containing All of a Given Set of Sports (But Possibly More) in SQL?

SQL:WHERE Joined Set 必须包含所有值,但可能包含更多

在 SQL 中,“WHERE JOINED SET”子句确保连接表在其结果集中包含特定值。但是,连接表还可能包含不属于条件的附加值。这个概念在实践中实施起来可能具有挑战性,特别是在确定条件中包含哪些值时。

考虑以下示例:

场景:

你有三个表:offer、sports 和 Offers_sports,分别代表 Offers、sports 以及它们之间的关系。您想要选择包含给定运动名称数组的优惠。优惠必须包含所有运动项目,但也可能包括其他运动项目。

数据:

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 |
登录后复制

期望结果:

给定数组 ["Bodyboarding", "Surfing"],查询应返回优惠媒介以及所有这些,因为它们包含两种指定的运动。优惠灯不应退回,因为它不包含这两种运动。

不正确的查询:

以下查询,按运动名称分组并确保恰好有两个每项优惠均包含体育运动,不退货结果:

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;
登录后复制

解决方案:

正确的查询按优惠 ID 而不是运动名称进行分组,并使用 COUNT( 检查每个优惠中包含的不同运动的数量DISTINCT):

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(DISTINCT sports.name) = ?", sport_names.size)
  end
end
登录后复制

以上是如何在 SQL 中选择包含所有给定体育项目(但可能更多)的报价?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板