仅从一组值中检索给定标识符和一个列值的多个条目中的行
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_ID
和COURSE_ID
s 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
另一答案
一种解决方案是返回状态为Enrolled
或Completed
的(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...
)
以上是关于仅从一组值中检索给定标识符和一个列值的多个条目中的行的主要内容,如果未能解决你的问题,请参考以下文章