优化查询从3个表mysql中选择元素

时间:2012-12-30 15:13:41

标签: mysql select join

数据库如下:

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
                        );

我认为可以写得更好。 (也许使用双联接?)

那么,如何优化(如果可以的话)?

3 个答案:

答案 0 :(得分:1)

如果没有看到您的预期结果,我的回答有点模糊,但无论如何这里都是一个试用的代码。叫我 visual ;)请在尝试查询后发表评论。

代码列表'每个类的挑战。您可以使用variable过滤掉特定class id的数据。

SQLFIDDLE DEMO

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)

答案 1 :(得分: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 

答案 2 :(得分: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