仅从一组值中检索给定标识符和一个列值的多个条目中的行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了仅从一组值中检索给定标识符和一个列值的多个条目中的行相关的知识,希望对你有一定的参考价值。

我有一个用于存储审计的数据库表,如下所示(它只是实际表的简单表示,其中STATUS可以有多个值之一)

ID | STUDENT_ID | COURSE_ID | STATUS
1  |     5      | 12        | Enrolled
2  |     5      | 12        | In-Progress
3  |     2      | 12        | Enrolled
4  |     2      | 12        | Completed
5  |     5      | 12        | Completed
6  |     2      | 14        | Enrolled

我需要找到给定STUDENT_ID和COURSE_ID对的所有记录作为标识符,其中STATUS属于已注册和已完成(即每个已注册和已完成状态有2条记录,或者只有一条记录为已注册或已完成状态)。

注意 - 对于给定的STUDENT_ID和COURSE_ID,不应存在一个条目,其中STATUS不是“已注册和已完成”。

输出表 -

ID | STUDENT_ID | COURSE_ID | STATUS
3  |     2      | 12        | Enrolled
4  |     2      | 12        | Completed
6  |     2      | 14        | Enrolled

更新 - 如果我有另一个STUDENT_ID 2条目,其状态为In-Progress,它仍然应该返回Status已注册和已完成的课程。

ID | STUDENT_ID | COURSE_ID | STATUS
1  |     5      | 12        | Enrolled
2  |     5      | 12        | In-Progress
3  |     2      | 12        | Enrolled
4  |     2      | 12        | Completed
5  |     5      | 12        | Completed
6  |     2      | 14        | Enrolled
7  |     2      | 14        | In-Progress

输出表 -

ID | STUDENT_ID | COURSE_ID | STATUS
3  |     2      | 12        | Enrolled
4  |     2      | 12        | Completed
答案

使用左连接和空测试

drop table if exists t;
create table t(ID int, STUDENT_ID int, COURSE_ID int, STATUS varchar(20));
insert into t values
(1  ,     5      , 12        , 'Enrolled'),
(2  ,     5      , 12        , 'In-Progress'),
(3  ,     2      , 12        , 'Enrolled'),
(4  ,     2      , 12        , 'Completed'),
(5  ,     5      , 12        , 'Completed'),
(6  ,     2      , 14        , 'Enrolled');


select t.* from t
left join
(select  student_id,course_id,count(*) from t where status not in('enrolled','completed') group by student_id,course_id) s
on t.STUDENT_ID = s.student_id and t.course_id = s.course_id 
where s.student_id is null;

+------+------------+-----------+-----------+
| ID   | STUDENT_ID | COURSE_ID | STATUS    |
+------+------------+-----------+-----------+
|    3 |          2 |        12 | Enrolled  |
|    4 |          2 |        12 | Completed |
|    6 |          2 |        14 | Enrolled  |
+------+------------+-----------+-----------+
3 rows in set (0.00 sec)
另一答案

我会排除STUDENT_IDCOURSE_IDs In-Progress状态:

select t.*
from table t
where not exists (select 1 
                  from table t1 
                  where t1.student_id = t.student_id and 
                        t1.course_id = t.course_id and t1.status = 'In-Progress'
                 );
另一答案

正如您所提到的,您只需要这两个状态 - '已注册','已完成'您可以通过子查询实现您的目标

SELECT t.* 
FROM   students t 
WHERE  student_id NOT IN (SELECT DISTINCT student_id 
                          FROM   students 
                          WHERE  status NOT IN ( 'Enrolled', 'Completed' ));
另一答案

使用distinct和子查询

 select distinct * from your_table 
    where STUDENT_ID not in 
      (  select STUDENT_ID from your_table 
         where STATUS in ('In-Progress')
      )

http://sqlfiddle.com/#!9/f6d650/1

ID  STUDENT_ID  COURSE_ID   STATUS
3     2         12          Enrolled
4     2         12          Completed
6     2         14          Enrolled

其他方式

select t1.* from
(
select * from yourtable 

) as t1

left join  
(
select * from yourtable
             where STATUS  in ('In-Progress')
) as t2 on t1.STUDENT_ID=t2.STUDENT_ID
where t2.id is null

http://sqlfiddle.com/#!9/f6d650/7

ID  STUDENT_ID  COURSE_ID   STATUS
3     2            12     Enrolled
4     2            12     Completed
6     2            14     Enrolled
另一答案

一种解决方案是返回状态为EnrolledCompleted的(STUDENT_ID,COURSE_ID)夫妇,但不返回任何其他内容:

select
  student_id,
  course_id
from
  students
group by
  student_id,
  course_id
having
  sum(status in ('Enrolled', 'Completed'))>0
  and sum(status not in ('Enrolled','Completed'))=0

然后你可以用这个提取所有列:

select *
from students
where
  (students_id, course_id) in (
    ..the select query above...
  )

以上是关于仅从一组值中检索给定标识符和一个列值的多个条目中的行的主要内容,如果未能解决你的问题,请参考以下文章

如何从给定的一组值中进行选择,四舍五入?

装箱问题 - 确定给定范围的一组值的最佳分组

如何确保一列包含一组值中的一个?

通过检索它们的值来自动检查复选框

C++ 在 Map 中的类的一组值中插入一个值

确定一个值是不是在 Java 中的一组值中的最快方法是啥?