查找与请求的值集完全匹配的内容

时间:2013-12-03 06:33:12

标签: db2 self-join

嗨,我正面临挑战。有一个表进展。

User_id | Assesment_id
-----------------------
1       | Test_1
2       | Test_1
3       | Test_1
1       | Test_2
2       | Test_2
1       | Test_3
3       | Test_3

我需要提取仅完成Test_1&的user_id。 test_2(即User_id:2)。输入参数将是Assesment id的列表。

修改

我希望那些已完成列表中所有评估的人,但没有其他人 用户3未完成Test_2,因此被排除在外 用户1完成了额外测试,也被排除在外 只有用户2完成了所要求的评估。

2 个答案:

答案 0 :(得分:0)

您不需要复杂的连接甚至子查询。只需使用INTERSECT运算符:

select user_id from progress where assessment_id = 'Test_1'
intersect
select user_id from progress where assessment_id = 'Test_2'

答案 1 :(得分:0)

我将您的问题解释为您希望在评估列表中完成所有测试的用户,而不是任何其他测试。我将使用一种称为公用表表达式的技术,以便您可以按步骤进行操作,但它只是一个查询语句。

假设您将评估列表作为名为Checktests的表中的行提供。我们可以计算这些值,以找出需要多少测试。

如果我们使用LEFT OUTER JOIN,那么右侧表中的值将为null。因此,如果评估不在您的列表中,则test_matched列将为null。 COUNT()忽略空值,因此我们可以使用它来查明列表中已进行的测试数,然后将其与用户所进行的所有测试的数量进行比较。

with x as
(select count(assessment_id) as tests_needed
   from checktests
),
dtl as
(select p.user_id, 
        p.assessment_id  as test_taken,
        c.assessment_id  as test_matched
   from progress p
   left join checktests c   on p.assessment_id = c.assessment_id
),
y as
(select user_id, 
        count(test_taken)    as all_tests,
        count(test_matched)  as wanted_tests  -- count() ignores nulls
   from dtl
   group by user_id
)
select user_id
  from y
  join x     on y.wanted_tests = x.tests_needed 
  where         y.wanted_tests = y.all_tests ;