2

次のテーブルがあります:
Person、{"Id"、 "Name"、 "LastName"}
Sports、{"Id" "Name"、 "Type"}
SportsPerPerson、{"Id"、 "PersonId"、 "SportsId"}

私のクエリでは、特定のスポーツを行使するすべての人を取得したいのに対し、私はスポーツの「名前」属性しか使用できません。正しい行を取得するために、次のクエリを見つけました。

SELECT *
FROM Person
WHERE Person.Id in 
(
    SELECT SportsPerPerson.PersonId FROM SportsPerPerson
    INNER JOIN Sports on SportsPerPerson.SportsId = Sports.Id
    WHERE Sports.Name = 'Tennis'
)
AND Person.Id in 
(
    SELECT SportsPerPerson.PersonId FROM SportsPerPerson
    INNER JOIN Sports on SportsPerPerson.SportsId = Sports.Id
    WHERE Sports.Name = 'Soccer'
)

また

SELECT *
FROM Person
WHERE Id IN
    (SELECT PersonId FROM SportsPerPerson WHERE SportsId IN 
        (SELECT Id FROM Sports WHERE Name = 'Tennis'))
AND Id IN
    (SELECT PersonId FROM SportsPerPerson WHERE SportsId IN 
        (SELECT Id FROM Sports WHERE Name = 'Soccer'))

今私の質問は、このクエリを書くためのより簡単な方法はありませんか?「テニス」と「サッカー」をプレイする人が必要なため、ORだけを使用しても機能しません。ただし、値が同じ行にないため、ANDを使用しても機能しません。

4

5 に答える 5

2

別のものを使用JOINして、2番目を回避できますIN。副選択は、テニスとサッカーの両方をプレイする人のみを返します。

SELECT *
FROM Person
WHERE Person.Id IN
(
    SELECT spp1.PersonId
    FROM SportsPerPerson spp1
    JOIN SportsPerPerson spp2 ON ( spp2.PersonId = spp1.PersonId )
    JOIN Sports s1 on spp1.SportsId = s1.Id
    JOIN Sports s2 on spp2.SportsId = s2.Id
    WHERE s1.Name = 'Tennis'
      AND s2.Name = 'Soccer'
)
于 2010-05-11T07:37:55.720 に答える
1

クエリでは2つの結合を使用する必要があります。

SELECT *
FROM Person p INNER JOIN SportsPerPerson spp1 ON (p.PersonId = spp1.PersonId)
              INNER JOIN Sports s1 ON (s1.SportsIN = spp1.SportId)
              INNER JOIN SportsPerPerson spp2 ON (p.PersonId = spp2.PersonId)
              INNER JOIN Sports s2 ON (s2.SportId = spp2.SportId)
    WHERE s1.Name = 'Tennis' AND s2.Name='Soccer'
于 2010-05-11T07:35:30.113 に答える
0

秘訣は、同じテーブルを複数回使用できるようにエイリアスを使用することです。

SELECT p.*
FROM Person p
INNER JOIN SportsPerPerson spa
  ON p.Id = spa.PersonId
INNER JOIN Sports sa
  ON spa.SportsId = sa.Id
INNER JOIN SportsPerPerson spb
  ON p.Id = spb.PersonId
INNER JOIN Sports sb
  ON spb.SportsId = sb.Id
WHERE
  sa.Name = 'Tennis'
  AND sb.Name = 'Soccer'
于 2010-05-11T07:39:04.040 に答える
0

これ:

SELECT  *
FROM    Person p
WHERE   (
        SELECT  COUNT(*)
        FROM    Sports s
        JOIN    SportsPerPerson sp
        ON      sp.SportsID = s.id
        WHERE   s.name IN ('Tennis', 'Soccer')
                AND sp.PersonID = p.id
        ) = 2

またはこれ:

SELECT  p.*
FROM    (
        SELECT  sp.PersonID
        FROM    Sports s
        JOIN    SportsPerPerson sp
        ON      sp.SportsID = s.id
        WHERE   s.name IN ('Tennis', 'Soccer')
        GROUP BY
                sp.PersonID
        HAVING  COUNT(*) = 2
        ) q
JOIN    person p
ON      p.id = q.personID

これを正しく高速に機能させるには、aUNIQUE KEYまたはPRIMARY KEYonを宣言する必要があります。SportsPerPerson (sportsid, personid)

于 2010-05-11T07:41:10.527 に答える
0

必要なクエリは次のとおりです。

SELECT p.ID, p.Name, p.LastName
FROM Person p
JOIN SportsPerPerson sp ON p.ID = sp.PersonID 
JOIN Sports s ON sp.SportsID = s.ID
WHERE s.Name = 'Football'

とはいえ、余談ですが、SportsPerPersonテーブルのIDキーは、多対多の関係を実装するために完全に不要です。PersonID列とSportID列を複合主キーとして使用するだけで十分です。

于 2010-05-11T07:51:31.920 に答える