>데이터 베이스 >MySQL 튜토리얼 >SQL에서 주어진 모든 스포츠 세트(그러나 더 많은 스포츠 세트)를 포함하는 제안을 선택하는 방법은 무엇입니까?

SQL에서 주어진 모든 스포츠 세트(그러나 더 많은 스포츠 세트)를 포함하는 제안을 선택하는 방법은 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-12-27 13:49:10312검색

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 및 Offer_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;

이 쿼리는 지정된 두 가지 모두를 포함하므로 매체와 모든 제안을 반환합니다. sports.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.