집 >데이터 베이스 >MySQL 튜토리얼 >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 중국어 웹사이트의 기타 관련 기사를 참조하세요!