仅检索关节具有依赖关系的行

时间:2015-03-10 22:58:38

标签: mysql sql subquery

我正在创建一个测试系统,允许用户重新测试,直到他们通过。我想获得一个列表,对于给定的UserID,分配给他们的测试,他们得分低于传递(本例中为100%)。

我有以下表格:

  

(这里的所有内容都是为了简化而改编的,但它仍然有效)

Users
(Generic "users" table with UserID and Name, etc...)

Tests
+--------+----------+------------------+
| TestID | TestName | OtherTestColumns |
+--------+----------+------------------+
|      1 |   Test 1 |         Blah.... |
|      2 |   Test 2 |         Blah.... |
|      3 |   Test 3 |         Blah.... |
|      4 |   Test 4 |         Blah.... |
+--------+----------+------------------+

Users_Have_Tests
  Users are assigned tests they must take with this table
+--------+--------+
| UserID | TestID |
+--------+--------+
|      1 |      1 |
|      1 |      2 |
|      1 |      3 |
|      2 |      1 |
|      2 |      2 |
|      2 |      3 |
+--------+--------+

TestResults
+--------+--------+------------+
| TestID | UserID | Percentage |
+--------+--------+------------+
|      1 |      1 |         75 |
|      1 |      1 |        100 |
|      2 |      1 |         80 |
|      2 |      1 |        100 |
|      1 |      2 |        100 |
|      2 |      2 |         75 |
+--------+--------+------------+

以下查询适用于我找出分配给用户的所有测试,但我想删除他们从此列表中传递的测试

SELECT DISTINCT
    TestID,
    TestName
FROM
    `Users` AS u
RIGHT JOIN
    `Users_have_Tests` AS ut
    ON
        u.UserID = ut.UserID
LEFT JOIN
    `Tests` AS t
    ON
        ut.TestID = t.TestID
WHERE UserID = 1

我觉得我需要一个子查询。我想出了以下查询来查找用户每次测试的最大分数,但我不太确定如何将它们绑在一起。 (子查询对我来说很新,我仍然试图理解它们。)

SELECT DISTINCT
    TestID,
    MAX(Percentage)
FROM
    `TestResults`
WHERE UserID = 1
GROUP BY TestID

我正在寻找的结果是:

UserID = 1
+--------+----------+
| TestID | TestName |
+--------+----------+
|      3 |   Test 3 |
+--------+----------+

UserID = 2
+--------+----------+
| TestID | TestName |
+--------+----------+
|      2 |   Test 2 |
|      3 |   Test 3 |
+--------+----------+

我尝试了几种连接方式和条件,但我无法完全理解我在这里需要的东西。谷歌和StackOverflow让我失望;可能是因为我缺乏搜索内容的知识。

修改 以下是对我有用的:

SELECT DISTINCT t.TestID, t.TestName
    FROM 'Users' AS u
    RIGHT JOIN 'Users_have_Tests' AS ut
        ON u.UserID = ut.UserID
    LEFT JOIN 'Tests' AS t
        ON ut.TestID = t.TestID
    WHERE t.TestID NOT IN (
        SELECT tr.TestID
            FROM TestResults AS tr
            WHERE tr.Percentage >= 100
            AND tr.UserID = 2
        )
    AND u.UserID = 2

4 个答案:

答案 0 :(得分:1)

您是否尝试过以下操作?

编辑我注意到你想看到最高分,所以我创建了一个子查询

编辑我忘记了分组。

此外,还需要在TestID和UserID上加入Test。

        SELECT
            TestID,
            TestName,
            HighestScore
        FROM
            `Users` AS u
        RIGHT JOIN
            `Users_have_Tests` AS ut
            ON
                u.UserID = ut.UserID
        LEFT JOIN
        (   SELECT TestID, UserID, MAX(Percentage) AS HighestScore
            FROM `Tests`
            GROUP BY TestID, UserID         
        )AS t
            ON
                ut.TestID = t.TestID
            AND ut.UserID = t.UserID
        WHERE HighestScore < 100
        GROUP BY TestID, TestName, HighestScore

答案 1 :(得分:1)

我想我现在明白你的意思,试一试:

SELECT DISTINCT
        TestID,
        TestName
    FROM
        `Users` AS u
    RIGHT JOIN
        `Users_have_Tests` AS ut
        ON
            u.UserID = ut.UserID
    LEFT JOIN
        `Tests` AS t
        ON
            ut.TestID = t.TestID
    WHERE TestID NOT IN (SELECT TestID
                         FROM TestResults
                         Where Percentage = 100)
    GROUP BY UserID

答案 2 :(得分:0)

我可能会遗漏一些东西,但为什么不运行以下查询并处理结果呢?

    SELECT ut.UserId, ut.TestId, t.TestName
    FROM `Users_Have_Tests` ut INNER JOIN `TestResults` r ON ut.TestId = r.TestId
      INNER JOIN `Tests` t ON t.TestId = r.TestId
    WHERE r.Percentage < 100
    ORDER BY ut.UserId, ut.TestId;

如果您打算为单个用户执行此操作,只需添加WHERE子句条目以针对单个UserId值进行过滤。

答案 3 :(得分:0)

尝试有条款

之后

MAX(百分比)AS最高分数

小组之后说

拥有最高分数&lt; 100

然后用最低通过分数替换100 ..只返回没有超过最大条目的测试。

http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html