0

データベースは次のとおりです。

Classes       Challenges         Class Challenges
id             id                  id
               title               class_id
                                   challenge_id

特定のクラスのすべての課題を取得するために、次を使用します

SELECT 
    DISTINCT class_challenges.challenge_id, 
    challenges.title
FROM class_challenges 
LEFT JOIN challenges 
    ON class_challenges.challenge_id = challenges.id
WHERE class_challenges.class_id = :class_id
ORDER BY challenge_id

特定のクラスに属さないすべての課題に対して同じことを行うにはどうすればよいですか? これまでのところ、私は使用しています:

SELECT 
    DISTINCT challenges.id,
    challenges.title 
FROM 
    challenges,
    class_challenges
WHERE challenges.id NOT IN(
                            SELECT 
                                DISTINCT class_challenges.challenge_id
                            FROM class_challenges
                            LEFT JOIN challenges 
                                ON class_challenges.challenge_id = challenges.id
                            WHERE class_challenges.class_id = :class_id
                            ORDER BY challenge_id
                        );

もっとうまく書けると思います。(おそらく二重結合を使用していますか?)

では、これをどのように最適化できますか (可能な場合)。

4

3 に答える 3

1

あなたの期待する結果を見ずに答えるのは少し曖昧ですが、とにかくここに試してみるコードがあります。ビジュアルと呼んでください;)クエリを試した後、コメントしてください。

コードリストには、「各クラスの課題」が記載されています。を使用しvariableて、特定ののデータを除外できますclass id

SQLFIDDLEデモ

SELECT DISTINCT a.id, 
group_concat(b.challenge_id) as challengeIs,
group_concat(c.title) as Titles
FROM Classes a
LEFT JOIN 
class_challenges b
ON a.id = b.class_id
LEFT JOIN challenges c
ON b.challenge_id = c.id
group by a.id
ORDER BY a.id;

結果:

ID      CHALLENGEIS     TITLES
100     11,15       a,c
200     15          b
300     11,15       a,c
400     (null)      (null)
500     15          b

特定のクラスに属していないチャレンジ

クエリのこの部分を追加できなかったことに気づきました。

クエリ:

-クラスに属していないチャレンジ

SELECT DISTINCT c.id,
c.title, group_concat(a.id) as class
FROM challenges c
LEFT JOIN 
class_challenges b
ON b.challenge_id = c.id
LEFT JOIN Classes a
ON a.id = b.class_id
GROUP BY c.id
HAVING class is null
ORDER BY c.id;

結果:

ID  TITLE   CLASS
18  c   (null)
于 2012-12-30T15:39:41.767 に答える
1

このクエリを試してください

SELECT
    t.id,
    t.title,
    t.CCID
FROM
(
    SELECT      
        challenges.id,
        challenges.title,
        class_challenges.id as CCID                 
    FROM 
        challenges
    LEFT JOIN class_challenges 
        ON class_challenges.challenge_id = challenges.id
) as t  
WHERE t.CCID IS NULL 
于 2012-12-30T18:18:11.297 に答える
0

アンチ結合を使用して、これはどうですか:

SELECT challenges.id, challenges.title
FROM challenges
LEFT JOIN class_challenges ON class_challenges.challenge_id = challenges.id
    AND class_challenges.class_id = :class_id
WHERE class_challenges.id IS NULL
于 2012-12-30T15:19:41.000 に答える