2016-07-23 61 views
2

我有表:Users(id,name,...),Knowledge(id,name,...)Courses(id,name....)。 每个用户都有多个“知识”(ManyToMany类型的用户和知识链接)。 例如,用户“用户1”具有2个知识“1”和“2”。 课程还通过ManyToMany类型与知识链接。但在这种情况下的知识是要求。 例如,课程“课程1”需要知识“1”和“2”,用户可以访问该课程。 课程“课程2”需要知识“1”和“3”,且用户无法访问此课程。如何为我的任务写出正确的sql请求

我想编写正确的sql命令,它返回所有课程,它可以获取用户。 我使用PostgresSql。 对不起,我可怕的英语。

我想这个SQL命令加入课程和知识:

select c.id as "Course id", k.requiredknowledge_id from course as c inner join courses_required_knowledges as k on k.course_id = c.id; 

类似的命令加入用户和知识。

select u.id as "User id", k.knowledge_id from user_info as u inner join users_knowledge as k on k.userInfo_id = u.id where u.id = 1; 

但我不知道如何“combain”此命令为GET结果

+1

请显示您到目前为止所尝试的内容。 – Serg

+1

编辑你的问题,并提供样本数据和期望的结果。另外,用您正在使用的数据库标记问题。 –

+0

我想,也许concat列值(group by)并比较它 –

回答

0
select c.id as "Course", array_agg(k.requiredknowledge_id) as "Requiried knoweldge" , array_agg(uk.knowledge_id) as "User Knowledge" 
from course as c 
right join courses_required_knowledges as k on k.course_id = c.id 
right join users_knowledge as uk on uk.userInfo_id = 1 
group by c.id 
having array_agg(k.requiredknowledge_id) <@ array_agg(uk.knowledge_id); 

这对我工作的例子。

0

你可能在寻找这样的事情。

首先,让我们创建一些测试数据:

create table course (id int primary key, name varchar(20)); 
insert into course (id, name) values 
(1,'cooking'), 
(2,'super hero'), 
(3,'otaku'); 

create table knowledge (id int primary key, name varchar(30)); 
insert into knowledge (id, name) values 
(4,'boil egg'), 
(5,'toast bread'), 
(6,'maintain secret identity'), 
(7,'read'); 

create table courses_required_knowledges (id int primary key, course_id int, requiredknowledge_id int); 
insert into courses_required_knowledges (id, course_id, requiredknowledge_id) values 
(8,1,4), 
(9,1,5), 
(10,2,6), 
(11,3,7); 

create table user_info (id int primary key, name varchar(20)); 
insert into user_info (id, name) values 
(12,'John Doe'), 
(13,'Konata'), 
(14,'Mega Mindy'); 

create table users_knowledge (id serial primary key, userInfo_id int, knowledge_id int); 
insert into users_knowledge (userInfo_id, knowledge_id) values 
(12,4), 
(12,7), 
(12,5), 
(13,7), 
(14,6), 
(14,7), 
(14,5); 

查询下方加入他们对记者的字段。
随着用户表交叉连接(全部到)所需的课程。

select 
-- course.id as course_id, 
-- coursereq.requiredknowledge_id, 
-- user_info.id as user_id, 
course.name as course, 
reqknow.name as required_knowledge, 
user_info.name as username, 
(case when users_knowledge.id is null then 'N' else 'Y' end) as user_meets_requirement 
from courses_required_knowledges as coursereq 
full outer join user_info on (1=1) 
left join users_knowledge 
    on (user_info.id = users_knowledge.userInfo_id and 
     coursereq.requiredknowledge_id = users_knowledge.knowledge_id) 
left join knowledge as reqknow 
    on (coursereq.requiredknowledge_id = reqknow.id) 
-- left join knowledge as usrknow 
-- on (users_knowledge.knowledge_id = usrknow.id) 
left join course 
    on (coursereq.course_id = course.id) 
where users_knowledge.id is null 
order by 
course.name, reqknow.name, user_info.name; 

这将给用户错过的要求注册课程。

结果:

course  required_knowledge  username user_meets_requirement 

cooking  boil egg     Konata  N 
cooking  boil egg     Mega Mindy N 
cooking  toast bread    Konata  N 
super hero maintain secret identity John Doe N 
super hero maintain secret identity Konata  N 
+0

感谢您的回答,但我在ManyToMany的问题表链接中犯了大错。我将编辑我的问题 –

+0

我对这些名字有一些乐趣。 – LukStorms